Compare commits

...

53 Commits

Author SHA1 Message Date
John Crispin
2983d9ca2b ath11k-wifi: add trailing '\' in Makefile
This caused image to pop up builds with no BDF in the image.

Fixes: 1a305421 (ipq807x: add support for wallystech dr6018)
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-29 08:36:21 +02:00
John Crispin
2283a64e57 ipq807x: backport eBPF layer from v5.10 kernel
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 19:40:05 +02:00
John Crispin
1a3054218f ipq807x: add support for wallystech dr6018
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 19:40:05 +02:00
John Crispin
7d26b55cb5 Dockerfile: install llvm/clang
This is required by the bpf-header compat package.

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 19:40:05 +02:00
John Crispin
cd85723609 ipq807x: fix v4.4 kernel-headers for BPF
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 10:15:58 +02:00
John Crispin
6d922da9b8 backports: add iproute2 compile fix
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 10:15:58 +02:00
John Crispin
6b81555bb2 backports: add bpf-headers compat layer
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 10:15:58 +02:00
John Crispin
267157563e ucentral-schema: update to latest HEAD
1bdc8de update the qos scheme/renderer

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 10:15:58 +02:00
John Crispin
6505ca0a8f hostapd: fix qos_map_set
The option was incorrectly masked by iw_enable.

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 10:15:58 +02:00
John Crispin
5cafdaea60 profiles: add qosify to the ap profile
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 10:15:58 +02:00
John Crispin
4a3d4f5609 qosify: add new QoS package
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-28 10:15:58 +02:00
John Crispin
3085dc78ef ucode: update to latest HEAD
* adds resolv module

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-27 18:21:02 +02:00
John Crispin
897ab17137 ucentral-schema: update to latest HEAD
6b3bdb1 force dnsmasq reload after applying a config

Fixes: WIFI-5025
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-22 18:05:38 +02:00
John Crispin
840319e24f udevmand: update to latest HEAD
b5a68ca fix wrap around glitch

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-22 10:35:53 +02:00
John Crispin
00197d703e ath11k: fix regdb upload
Make ath11k honour latest regdb.

Fixes: WIFI-3256
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-22 10:27:47 +02:00
John Crispin
a290ad3764 ucentral-schema: update to latest HEAD
d59450b add bssid to radio stats

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-22 08:18:50 +02:00
John Crispin
972eea34eb ucentral-client: update to latest HEAD
0179c0f Drop 60s socket timeout

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-22 08:17:48 +02:00
John Crispin
851507921a hostapd: add wds fixes to AX hostapd
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-22 08:15:43 +02:00
John Crispin
b364ab3064 certificates: fix the file owner and permission of the certificates
This was breaking hostapd local-certificates support.

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-22 07:58:20 +02:00
John Crispin
45143cc2c9 chilli-redirect: add uamsecret to list of possible options
Fixes: WIFI-4935
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-21 16:02:28 +02:00
John Crispin
895e501b93 hostapd: update to latest HEAD
This fixes an issue where WDS would not work reliably upon AP->STA transition.

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-21 11:33:58 +02:00
John Crispin
7d9594c3c8 netifd: update to latest HEAD
This fixes an issue where WDS would not work reliably upon AP->STA transition.

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-21 11:33:25 +02:00
John Crispin
485c689408 ipq807x: add support for wf194c4
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-20 08:23:04 +02:00
John Crispin
ec2e24e982 workflow: update wf-188 and ec-420 profile
This will let FMS properly pick the files up.

Fixes: WIFI-4929
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-18 10:10:07 +02:00
John Crispin
32f86e2d77 ucentral-event: update to latest HEAD
7b0d136 align event names

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-18 09:32:50 +02:00
John Crispin
53e73b24de ucentral-schema: update metric example
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-18 08:58:36 +02:00
John Crispin
e57dad9009 ucentral-schema: update to latest HEAD
0456fc4 telemetry task was not getting enqueued in the correct runqueue

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-18 08:58:17 +02:00
John Crispin
01c3ce4fc7 ucentral-wifi: update to latest HEAD
b6dd24f add bssid to wifi scan results

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-18 07:01:16 +02:00
John Crispin
6b3d2b8059 ipq40xx: add spw2ac1200-lan-poe profile
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-14 16:22:24 +02:00
John Crispin
ba079bea9f linksys_ea6350-v4: make sure the image land in S3 with the correct name
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-14 12:39:38 +02:00
John Crispin
f971f3a4d4 luci-mod-ucentral: the unit was not correctly rebooting after "save & apply"
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-14 12:12:42 +02:00
Stijn Tintel
32524c19bd This is required for Express Wi-Fi in bridged mode
Fixes: WIFI-4639
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2021-10-13 18:17:52 +02:00
John Crispin
966353e747 ucentral-schema: update to latest HEAD
73e9fbc open-flow: support OpenFlow bridged mode
ac24d7f drop vlan-id from the gre tunnel definition

Fixes: WIFI-4639
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-13 18:17:46 +02:00
John Crispin
37f30d95f8 ucentral-schema: update to latest HEAD
7e59b14 only generate docs if the tool is installed
e440ced open-flow: fix controller property type
b85abaf generate-reader.uc: introduce ip format
288997c open-flow: update generated files
e9d7049 generate.sh: generate schemareader.uc before docs

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-13 16:44:19 +02:00
John Crispin
e699bebac7 fbwifi: sync with latest HEAD
Fixes: WIFI-4910
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-13 14:08:12 +02:00
John Crispin
0e5ec91a12 luci: start using the upstream feed and move the maverick packages into the tree
Fixes: WIFI-4911
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-13 13:01:39 +02:00
John Crispin
3cad34e1b9 certififcates: reduce log noise when mounting the certificates partition
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-13 10:51:21 +02:00
Stijn Tintel
2c37a6983f openflow: sync changes from openwrt-packages
c05103da9 openvswitch: add option for OpenFlow datapath desc
 b2bfb572a openvswitch: fix build with libunbound
 9e45d4534 openvswitch: add option for failure mode

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2021-10-13 07:37:16 +02:00
John Crispin
330eead632 ipq40xx: improve SPW2AC1200 sysupgrade
with this fix it does not matter if the unit is in primary or secondary boot mode.

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-12 18:25:57 +02:00
John Crispin
f1456f321a ipq807x: update eap102 bdf
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-12 18:25:42 +02:00
John Crispin
9152942d93 ucentral-schema: update to latest HEAD
60549a8 open-flow: use mode ssl by default
70d8465 openflow: remove duplicate code
2718e30 schema: add property to set OpenFlow datapath description

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-12 11:05:20 +02:00
John Crispin
f202250a68 ucentral-schema: update to latest HEAD
50d182c renderer: add missing support for hostapd_bss_raw and hostapd_iface_raw

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-12 10:53:49 +02:00
John Crispin
fad14af474 ipq40xx: improve EdgeCore-SPW2AC1200 sysupgrade
Make sure to always flash into the primary partition.

Signed-off-by: John Crispin <john@phrozen.org>
2021-10-12 08:13:11 +02:00
John Crispin
5a7bafede0 ucentral-schema: update to latest HEAD
8eb586b 11u domain operator name was a singleton but should be an array
4eb1560 iw_nai_realm was being written to uci using set and not add_list
a35a0ea add support for hs20_wan_metrics

Fixes: WIFI-4868
Fixes: WIFI-4869
Fixes: WIFI-4870
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-11 11:51:39 +02:00
John Crispin
6738a933ab ucentral-schema: add example vlan config for switches
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-09 08:11:16 +02:00
John Crispin
a46262aaaa hostapd: fix wpa3-eap modes
wpa3 was not setup correctly and wpa3-192 was missing

Fixes: WIFI-4281
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-07 14:08:17 +02:00
John Crispin
2988180211 maverick: fix feature on single port devices
On single port devices no logical lan interface was setup resulting in
clients associating not being provided with DHCP.

Fixes: WIFI-4641
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-07 09:07:37 +02:00
John Crispin
ec0d693d12 ath79: add certificates partition for indio device
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-05 16:38:32 +02:00
John Crispin
406dad6604 chilli: fix log spam when coova is not used
Fixes: WIFI-4471
Signed-off-by: John Crispin <john@phrozen.org>
2021-10-01 09:38:30 +02:00
John Crispin
b31b236646 mac80211: do not hard abort when iw times out
Signed-off-by: John Crispin <john@phrozen.org>
2021-09-29 15:20:50 +02:00
John Crispin
0c379ed26c netifd: update to latest HEAD
e467e0f wireless: reset retry counter when setup succeeds
0e311d3 wireless: reset number of retries on config change
62e2bb5 main: poll process log stream even if processes are killed
fac471c wireless: process and close script file descriptor when rerunning setup
186f6ea wireless: display log messages for setup/teardown/retry
4d0c2ad wireless: fix applying wireless devices attributes on hotplug events

Signed-off-by: John Crispin <john@phrozen.org>
2021-09-29 15:20:31 +02:00
Max
647d5c8a33 workflow: trigger testing workflow for new releases (#385)
Signed-off-by: Max Brenner <xamrennerb@gmail.com>
2021-09-29 14:19:52 +02:00
Stijn Tintel
7baf962bb8 fbwifi: update to git HEAD
b67be64 fbwifi: fix token validation script

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2021-09-29 14:19:21 +02:00
107 changed files with 55518 additions and 564 deletions

View File

@@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
target: ['cig_wf188', 'cig_wf194c', 'cig_wf160d', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'hfcl_ion4.yml', 'indio_um-305ac', 'linksys_ea6350', 'linksys_e8450-ubi', 'linksys_ea8300', 'tplink_ec420', 'tplink_ex227', 'tplink_ex228', 'tplink_ex447', 'wallys_dr40x9' ]
target: ['cig_wf188n', 'cig_wf194c', 'cig_wf194c4', 'cig_wf160d', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4.yml', 'indio_um-305ac', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'tp-link_ec420-g1', 'tplink_ex227', 'tplink_ex228', 'tplink_ex447', 'wallys_dr40x9' ]
steps:
- uses: actions/checkout@v2
@@ -61,3 +61,16 @@ jobs:
[ -f openwrt/tmp/image-file ] && aws s3 cp --acl public-read --content-type "application/octet-stream" "openwrt/$(cat openwrt/tmp/image-file)" "s3://$AWS_S3_BUCKET_NAME/$IMG_NAME"
[ -f openwrt/tmp/image-file ] && aws s3 cp --acl public-read --content-type "application/json" "latest-upgrade.json" "s3://$AWS_S3_BUCKET_NAME/$JSON_NAME"
trigger-testing:
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Trigger testing of release
uses: peter-evans/repository-dispatch@v1
with:
token: ${{ secrets.WLAN_TESTING_PAT }}
repository: Telecominfraproject/wlan-testing
event-type: new-ap-release
client-payload: '{"ref": "${GITHUB_REF#refs/tags/}", "sha": "${{ github.sha }}"}'

View File

@@ -1,17 +1,21 @@
From 85aa45ef0dc90e50e9ac0931fd2a8c99c764e101 Mon Sep 17 00:00:00 2001
From c9e9ca475bc2eb90beb23a2c67c39389f8cb2527 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 27 May 2021 13:24:47 +0200
Subject: [PATCH 01/58] netifd: update to latest HEAD
Signed-off-by: John Crispin <john@phrozen.org>
---
package/network/config/netifd/Makefile | 8 +++-----
.../netifd/patches/002-fix-dhcp-issue.patch | 17 +++++++++++++++++
2 files changed, 20 insertions(+), 5 deletions(-)
package/network/config/netifd/Makefile | 8 ++--
.../netifd/patches/002-fix-dhcp-issue.patch | 17 +++++++++
.../config/netifd/patches/100-script.patch | 21 +++++++++++
.../config/netifd/patches/hairpin.patch | 37 +++++++++++++++++++
4 files changed, 78 insertions(+), 5 deletions(-)
create mode 100644 package/network/config/netifd/patches/002-fix-dhcp-issue.patch
create mode 100644 package/network/config/netifd/patches/100-script.patch
create mode 100644 package/network/config/netifd/patches/hairpin.patch
diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile
index 4b5f110da2..276633cfa7 100644
index 4b5f110da2..d41bddfd56 100644
--- a/package/network/config/netifd/Makefile
+++ b/package/network/config/netifd/Makefile
@@ -5,16 +5,14 @@ PKG_RELEASE:=1
@@ -21,9 +25,9 @@ index 4b5f110da2..276633cfa7 100644
-PKG_SOURCE_DATE:=2021-07-26
-PKG_SOURCE_VERSION:=440eb0647708274cc8d7d9e7c2bb0cfdfba90023
-PKG_MIRROR_HASH:=eed957036ab608fdc49bdf801fc5b4405fcd2a3a5e5d3343ec39898e156c10e9
+PKG_SOURCE_DATE:=2021-09-01
+PKG_SOURCE_VERSION:=5a4ac30c7a15712d01110befec1acfe86c2cbed0
+PKG_MIRROR_HASH:=888d40c88997a628be2a6d7f7a1de1c7fed742f4c19312c52cdf5a72b26a96af
+PKG_SOURCE_DATE:=2021-10-20
+PKG_SOURCE_VERSION:=c61a1d432b34babe230e49a82712608b07410fc3
+PKG_MIRROR_HASH:=2b040d039c560cbc04dfe1e496aa81f714a032db88986803728dd6b724c11cd2
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=GPL-2.0
@@ -57,6 +61,76 @@ index 0000000000..6f1d2e708e
+ return;
+ default:
+ break;
diff --git a/package/network/config/netifd/patches/100-script.patch b/package/network/config/netifd/patches/100-script.patch
new file mode 100644
index 0000000000..e7ba83f4bb
--- /dev/null
+++ b/package/network/config/netifd/patches/100-script.patch
@@ -0,0 +1,21 @@
+Index: a/scripts/netifd-wireless.sh
+===================================================================
+--- a/scripts/netifd-wireless.sh
++++ b/scripts/netifd-wireless.sh
+@@ -252,11 +252,14 @@ wireless_vif_parse_encryption() {
+ auth_type=owe
+ ;;
+ wpa3-mixed*)
+- auth_type=eap-eap192
++ auth_type=eap-eap256
+ ;;
+- wpa3*)
++ wpa3-192*)
+ auth_type=eap192
+ ;;
++ wpa3*)
++ auth_type=eap256
++ ;;
+ psk3-mixed*|sae-mixed*)
+ auth_type=psk-sae
+ ;;
diff --git a/package/network/config/netifd/patches/hairpin.patch b/package/network/config/netifd/patches/hairpin.patch
new file mode 100644
index 0000000000..25515d75d4
--- /dev/null
+++ b/package/network/config/netifd/patches/hairpin.patch
@@ -0,0 +1,37 @@
+diff --git a/wireless.c b/wireless.c
+index b26c4e8c8f0b..bd847e72ab40 100644
+--- a/wireless.c
++++ b/wireless.c
+@@ -804,20 +804,13 @@ wireless_interface_init_config(struct wireless_interface *vif)
+ vif->network = cur;
+
+ cur = tb[VIF_ATTR_MODE];
+- if (cur)
+- vif->ap_mode = !strcmp(blobmsg_get_string(cur), "ap");
+-
+- if (!vif->ap_mode)
+- return;
++ vif->ap_mode = cur && !strcmp(blobmsg_get_string(cur), "ap");
+
+ cur = tb[VIF_ATTR_ISOLATE];
+- if (cur)
+- vif->isolate = blobmsg_get_bool(cur);
++ vif->isolate = vif->ap_mode && cur && blobmsg_get_bool(cur);
+
+ cur = tb[VIF_ATTR_PROXYARP];
+- if (cur)
+- vif->proxyarp = blobmsg_get_bool(cur);
+-
++ vif->proxyarp = vif->ap_mode && cur && blobmsg_get_bool(cur);
+ }
+
+ /* vlist update call for wireless interface list */
+@@ -846,8 +839,6 @@ vif_update(struct vlist_tree *tree, struct vlist_node *node_new,
+ wireless_interface_handle_link(vif_old, NULL, false);
+ free(vif_old->config);
+ vif_old->config = blob_memdup(vif_new->config);
+- vif_old->isolate = vif_new->isolate;
+- vif_old->ap_mode = vif_new->ap_mode;
+ wireless_interface_init_config(vif_old);
+ free(vif_new);
+ } else if (vif_new) {
--
2.25.1

View File

@@ -1,7 +1,7 @@
From 4381103753770dab05cb94045a60573e4863fca5 Mon Sep 17 00:00:00 2001
From 6718e9786f18dd1380e5977d224d13a5ff3df619 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sat, 4 Sep 2021 05:47:27 +0200
Subject: [PATCH 01/53] mac80211: update to latest HEAD
Subject: [PATCH 02/58] mac80211: update to latest HEAD
Signed-off-by: John Crispin <john@phrozen.org>
---
@@ -9,7 +9,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
package/kernel/mac80211/ath.mk | 5 +-
package/kernel/mac80211/broadcom.mk | 4 +-
.../mac80211/files/lib/netifd/mac80211.sh | 36 -
.../files/lib/netifd/wireless/mac80211.sh | 184 ++-
.../files/lib/netifd/wireless/mac80211.sh | 186 ++-
.../mac80211/files/lib/wifi/mac80211.sh | 110 +-
.../patches/ath/120-owl-loader-compat.patch | 53 -
.../patches/ath/402-ath_regd_optional.patch | 2 +-
@@ -75,7 +75,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
...eck-per-vif-offload_flags-in-Tx-path.patch | 26 +
.../500-mac80211_configure_antenna_gain.patch | 16 +-
...the-dst-buffer-to-of_get_mac_address.patch | 237 +++
70 files changed, 2751 insertions(+), 1159 deletions(-)
70 files changed, 2752 insertions(+), 1160 deletions(-)
delete mode 100644 package/kernel/mac80211/files/lib/netifd/mac80211.sh
delete mode 100644 package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch
rename package/kernel/mac80211/patches/{ath => ath10k}/080-ath10k_thermal_config.patch (97%)
@@ -286,7 +286,7 @@ index 92e5c0e395..0000000000
- done
-}
diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
index 9a9c35fb5f..a58af1fef0 100644
index 9a9c35fb5f..a25e4ff9b2 100644
--- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
+++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
@@ -1,7 +1,6 @@
@@ -535,6 +535,15 @@ index 9a9c35fb5f..a58af1fef0 100644
[ -n "$phy" ] && return 0
}
[ -n "$macaddr" ] && {
@@ -528,7 +630,7 @@ mac80211_iw_interface_add() {
rc="$?"
}
- [ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED
+ [ "$rc" != 0 ] && echo "Failed to create interface $ifname"
return $rc
}
@@ -689,14 +791,8 @@ mac80211_prepare_iw_htmode() {
case "$htmode" in
VHT20|HT20) iw_htmode=HT20;;

View File

@@ -1,4 +1,4 @@
From c51842eff4bcbc1def57e54d5eab0e5df2046d7e Mon Sep 17 00:00:00 2001
From beaf8ac8acf93bc617d3ed141c750fe1d4f2b047 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sat, 4 Sep 2021 05:48:27 +0200
Subject: [PATCH 01/56] hostapd: update to latest HEAD
@@ -8,7 +8,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
package/network/services/hostapd/Makefile | 15 +-
.../hostapd/files/hostapd-basic.config | 2 +-
.../hostapd/files/hostapd-full.config | 4 +-
.../network/services/hostapd/files/hostapd.sh | 145 +++++++--
.../network/services/hostapd/files/hostapd.sh | 181 +++++++++---
...-fix-frequency-setup-with-HE-enabled.patch | 196 -------------
...> 001-wolfssl-init-RNG-with-ECC-key.patch} | 11 +-
...-init-order-disable-pri-sec-channel-.patch | 126 --------
@@ -63,16 +63,17 @@ Signed-off-by: John Crispin <john@phrozen.org>
.../hostapd/patches/600-ubus_support.patch | 166 ++++++++---
.../hostapd/patches/700-wifi-reload.patch | 51 ++--
.../hostapd/patches/710-vlan_no_bridge.patch | 41 +++
.../patches/711-wds_bridge_force.patch | 26 ++
.../720-ACS-fix-channel-100-frequency.patch | 30 ++
.../patches/720-iface_max_num_sta.patch | 82 ++++++
.../hostapd/patches/730-ft_iface.patch | 38 +++
.../hostapd/patches/740-snoop_iface.patch | 66 +++++
.../hostapd/patches/740-snoop_iface.patch | 72 +++++
...ate-if-no-available-channel-is-found.patch | 37 ---
...of-secondary-device-types-for-P2P-gr.patch | 33 ---
.../services/hostapd/src/src/ap/ubus.c | 214 +++++++++++++-
.../services/hostapd/src/src/ap/ubus.h | 16 +
.../hostapd/src/src/utils/build_features.h | 2 -
67 files changed, 1280 insertions(+), 2335 deletions(-)
68 files changed, 1336 insertions(+), 2347 deletions(-)
delete mode 100644 package/network/services/hostapd/patches/001-HE-VHT-fix-frequency-setup-with-HE-enabled.patch
rename package/network/services/hostapd/patches/{802-wolfssl-init-RNG-with-ECC-key.patch => 001-wolfssl-init-RNG-with-ECC-key.patch} (76%)
delete mode 100644 package/network/services/hostapd/patches/002-mesh-fix-channel-init-order-disable-pri-sec-channel-.patch
@@ -103,6 +104,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
delete mode 100644 package/network/services/hostapd/patches/110-wolfssl-compile-fix.patch
delete mode 100644 package/network/services/hostapd/patches/120-reconfigure-wps-credentials.patch
create mode 100644 package/network/services/hostapd/patches/710-vlan_no_bridge.patch
create mode 100644 package/network/services/hostapd/patches/711-wds_bridge_force.patch
create mode 100644 package/network/services/hostapd/patches/720-ACS-fix-channel-100-frequency.patch
create mode 100644 package/network/services/hostapd/patches/720-iface_max_num_sta.patch
create mode 100644 package/network/services/hostapd/patches/730-ft_iface.patch
@@ -179,18 +181,31 @@ index df272e443a..61b6daf861 100644
# EAP-SAKE for the integrated EAP server
#CONFIG_EAP_SAKE=y
diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh
index aa72e09eba..c1f48326fa 100644
index aa72e09eba..0265c0518a 100644
--- a/package/network/services/hostapd/files/hostapd.sh
+++ b/package/network/services/hostapd/files/hostapd.sh
@@ -49,6 +49,7 @@ hostapd_append_wpa_key_mgmt() {
@@ -48,13 +48,17 @@ hostapd_append_wpa_key_mgmt() {
;;
eap192)
append wpa_key_mgmt "WPA-EAP-SUITE-B-192"
+ append wpa_key_mgmt "WPA-EAP-SHA256"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
+ [ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-EAP-SHA256"
;;
eap-eap192)
append wpa_key_mgmt "WPA-EAP-SUITE-B-192"
@@ -91,6 +92,7 @@ hostapd_add_log_config() {
- eap-eap192)
- append wpa_key_mgmt "WPA-EAP-SUITE-B-192"
+ eap-eap256)
append wpa_key_mgmt "WPA-EAP"
+ append wpa_key_mgmt "WPA-EAP-SHA256"
+ [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
+ ;;
+ eap256)
+ append wpa_key_mgmt "WPA-EAP-SHA256"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
- [ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-EAP-SHA256"
;;
sae)
append wpa_key_mgmt "SAE"
@@ -91,6 +95,7 @@ hostapd_add_log_config() {
hostapd_common_add_device_config() {
config_add_array basic_rate
config_add_array supported_rates
@@ -198,7 +213,7 @@ index aa72e09eba..c1f48326fa 100644
config_add_string country country3
config_add_boolean country_ie doth
@@ -99,6 +101,10 @@ hostapd_common_add_device_config() {
@@ -99,6 +104,10 @@ hostapd_common_add_device_config() {
config_add_string require_mode
config_add_boolean legacy_rates
config_add_int cell_density
@@ -209,7 +224,7 @@ index aa72e09eba..c1f48326fa 100644
config_add_string acs_chan_bias
config_add_array hostapd_options
@@ -115,7 +121,8 @@ hostapd_prepare_device_config() {
@@ -115,7 +124,8 @@ hostapd_prepare_device_config() {
local base_cfg=
json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
@@ -219,7 +234,7 @@ index aa72e09eba..c1f48326fa 100644
hostapd_set_log_options base_cfg
@@ -207,11 +214,16 @@ hostapd_prepare_device_config() {
@@ -207,11 +217,16 @@ hostapd_prepare_device_config() {
hostapd_add_rate brlist "$br"
done
@@ -236,7 +251,7 @@ index aa72e09eba..c1f48326fa 100644
json_get_values opts hostapd_options
for val in $opts; do
@@ -269,7 +281,7 @@ hostapd_common_add_bss_config() {
@@ -269,7 +284,7 @@ hostapd_common_add_bss_config() {
config_add_array domain_match domain_match2 domain_suffix_match domain_suffix_match2
config_add_string ieee80211w_mgmt_cipher
@@ -245,7 +260,7 @@ index aa72e09eba..c1f48326fa 100644
config_add_string vlan_tagged_interface vlan_bridge
config_add_string vlan_file
@@ -287,6 +299,7 @@ hostapd_common_add_bss_config() {
@@ -287,6 +302,7 @@ hostapd_common_add_bss_config() {
config_add_boolean wnm_sleep_mode wnm_sleep_mode_no_keys bss_transition
config_add_int time_advertisement
config_add_string time_zone
@@ -253,7 +268,7 @@ index aa72e09eba..c1f48326fa 100644
config_add_boolean ieee80211k rrm_neighbor_report rrm_beacon_report
@@ -311,6 +324,7 @@ hostapd_common_add_bss_config() {
@@ -311,6 +327,7 @@ hostapd_common_add_bss_config() {
config_add_array supported_rates
config_add_boolean sae_require_mfp
@@ -261,7 +276,7 @@ index aa72e09eba..c1f48326fa 100644
config_add_string 'owe_transition_bssid:macaddr' 'owe_transition_ssid:string'
@@ -319,23 +333,33 @@ hostapd_common_add_bss_config() {
@@ -319,23 +336,33 @@ hostapd_common_add_bss_config() {
config_add_int iw_ipaddr_type_availability iw_gas_address3
config_add_string iw_hessid iw_network_auth_type iw_qos_map_set
config_add_array iw_roaming_consortium iw_domain_name iw_anqp_3gpp_cell_net iw_nai_realm
@@ -298,7 +313,7 @@ index aa72e09eba..c1f48326fa 100644
}
hostapd_set_vlan_file() {
@@ -387,7 +411,7 @@ append_iw_anqp_3gpp_cell_net() {
@@ -387,7 +414,7 @@ append_iw_anqp_3gpp_cell_net() {
if [ -z "$iw_anqp_3gpp_cell_net_conf" ]; then
iw_anqp_3gpp_cell_net_conf="$1"
else
@@ -307,7 +322,7 @@ index aa72e09eba..c1f48326fa 100644
fi
}
@@ -399,10 +423,22 @@ append_iw_nai_realm() {
@@ -399,10 +426,22 @@ append_iw_nai_realm() {
[ -n "$1" ] && append bss_conf "nai_realm=$1" "$N"
}
@@ -330,7 +345,7 @@ index aa72e09eba..c1f48326fa 100644
append_osu_provider_service_desc() {
append bss_conf "osu_service_desc=$1" "$N"
}
@@ -450,6 +486,7 @@ append_osu_provider() {
@@ -450,6 +489,7 @@ append_osu_provider() {
append bss_conf "osu_method_list=$osu_method_list" "$N"
config_list_foreach "$1" osu_service_desc append_osu_provider_service_desc
@@ -338,7 +353,7 @@ index aa72e09eba..c1f48326fa 100644
config_list_foreach "$1" osu_icon append_osu_icon
append bss_conf "$N"
@@ -459,6 +496,14 @@ append_hs20_conn_capab() {
@@ -459,6 +499,14 @@ append_hs20_conn_capab() {
[ -n "$1" ] && append bss_conf "hs20_conn_capab=$1" "$N"
}
@@ -353,7 +368,7 @@ index aa72e09eba..c1f48326fa 100644
append_airtime_sta_weight() {
[ -n "$1" ] && append bss_conf "airtime_sta_weight=$1" "$N"
}
@@ -482,10 +527,12 @@ hostapd_set_bss_options() {
@@ -482,10 +530,12 @@ hostapd_set_bss_options() {
macfilter ssid utf8_ssid wmm uapsd hidden short_preamble rsn_preauth \
iapp_interface eapol_version dynamic_vlan ieee80211w nasid \
acct_server acct_secret acct_port acct_interval \
@@ -368,7 +383,7 @@ index aa72e09eba..c1f48326fa 100644
set_default isolate 0
set_default maxassoc 0
@@ -506,6 +553,7 @@ hostapd_set_bss_options() {
@@ -506,6 +556,7 @@ hostapd_set_bss_options() {
set_default multi_ap 0
set_default airtime_bss_weight 0
set_default airtime_bss_limit 0
@@ -376,7 +391,7 @@ index aa72e09eba..c1f48326fa 100644
append bss_conf "ctrl_interface=/var/run/hostapd"
if [ "$isolate" -gt 0 ]; then
@@ -532,6 +580,7 @@ hostapd_set_bss_options() {
@@ -532,6 +583,7 @@ hostapd_set_bss_options() {
append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
append bss_conf "utf8_ssid=$utf8_ssid" "$N"
append bss_conf "multi_ap=$multi_ap" "$N"
@@ -384,7 +399,7 @@ index aa72e09eba..c1f48326fa 100644
[ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N"
@@ -550,6 +599,7 @@ hostapd_set_bss_options() {
@@ -550,19 +602,21 @@ hostapd_set_bss_options() {
append bss_conf "acct_server_shared_secret=$acct_secret" "$N"
[ -n "$acct_interval" ] && \
append bss_conf "radius_acct_interim_interval=$acct_interval" "$N"
@@ -392,7 +407,15 @@ index aa72e09eba..c1f48326fa 100644
}
case "$auth_type" in
@@ -563,6 +613,7 @@ hostapd_set_bss_options() {
- sae|owe|eap192|eap-eap192)
+ sae|owe|eap192|eap256)
set_default ieee80211w 2
set_default sae_require_mfp 1
;;
- psk-sae)
+ psk-sae|eap-eap256)
set_default ieee80211w 1
set_default sae_require_mfp 1
;;
esac
[ -n "$sae_require_mfp" ] && append bss_conf "sae_require_mfp=$sae_require_mfp" "$N"
@@ -400,7 +423,13 @@ index aa72e09eba..c1f48326fa 100644
local vlan_possible=""
@@ -604,7 +655,7 @@ hostapd_set_bss_options() {
@@ -599,12 +653,12 @@ hostapd_set_bss_options() {
vlan_possible=1
wps_possible=1
;;
- eap|eap192|eap-eap192)
+ eap|eap192|eap-eap256|eap256)
json_get_vars \
auth_server auth_secret auth_port \
dae_client dae_secret dae_port \
ownip radius_client_addr \
@@ -409,7 +438,7 @@ index aa72e09eba..c1f48326fa 100644
# radius can provide VLAN ID for clients
vlan_possible=1
@@ -616,18 +667,22 @@ hostapd_set_bss_options() {
@@ -616,18 +670,22 @@ hostapd_set_bss_options() {
set_default auth_port 1812
set_default dae_port 3799
@@ -436,15 +465,17 @@ index aa72e09eba..c1f48326fa 100644
[ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N"
[ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N"
@@ -700,6 +755,7 @@ hostapd_set_bss_options() {
@@ -699,7 +757,8 @@ hostapd_set_bss_options() {
}
append bss_conf "ssid=$ssid" "$N"
[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
- [ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
+ [ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge${N}wds_bridge=" "$N"
+ [ -n "$network_ifname" ] && append bss_conf "snoop_iface=$network_ifname" "$N"
[ -n "$iapp_interface" ] && {
local ifname
network_get_device ifname "$iapp_interface" || ifname="$iapp_interface"
@@ -740,7 +796,7 @@ hostapd_set_bss_options() {
@@ -740,7 +799,7 @@ hostapd_set_bss_options() {
append bss_conf "ftm_responder=1" "$N"
[ "$stationary_ap" -eq "1" ] && append bss_conf "stationary_ap=1" "$N"
[ -n "$lci" ] && append bss_conf "lci=$lci" "$N"
@@ -453,7 +484,7 @@ index aa72e09eba..c1f48326fa 100644
}
fi
@@ -764,6 +820,7 @@ hostapd_set_bss_options() {
@@ -764,6 +823,7 @@ hostapd_set_bss_options() {
;;
esac
@@ -461,7 +492,7 @@ index aa72e09eba..c1f48326fa 100644
append bss_conf "mobility_domain=$mobility_domain" "$N"
append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N"
append bss_conf "ft_over_ds=$ft_over_ds" "$N"
@@ -778,6 +835,13 @@ hostapd_set_bss_options() {
@@ -778,6 +838,13 @@ hostapd_set_bss_options() {
set_default r0_key_lifetime 10000
set_default pmk_r1_push 0
@@ -475,7 +506,25 @@ index aa72e09eba..c1f48326fa 100644
[ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N"
append bss_conf "r0_key_lifetime=$r0_key_lifetime" "$N"
append bss_conf "pmk_r1_push=$pmk_r1_push" "$N"
@@ -863,13 +927,17 @@ hostapd_set_bss_options() {
@@ -822,7 +889,16 @@ hostapd_set_bss_options() {
json_get_vars ieee80211w_mgmt_cipher ieee80211w_max_timeout ieee80211w_retry_timeout
append bss_conf "ieee80211w=$ieee80211w" "$N"
[ "$ieee80211w" -gt "0" ] && {
- append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N"
+ case "$auth_type" in
+ eap192)
+ append bss_conf "group_mgmt_cipher=BIP-GMAC-256" "$N"
+ append bss_conf "group_cipher=GCMP-256" "$N"
+ ;;
+ *)
+ append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N"
+ ;;
+ esac
+
[ -n "$ieee80211w_max_timeout" ] && \
append bss_conf "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N"
[ -n "$ieee80211w_retry_timeout" ] && \
@@ -863,13 +939,17 @@ hostapd_set_bss_options() {
}
[ -n "$vlan_possible" -a -n "$dynamic_vlan" ] && {
@@ -495,7 +544,7 @@ index aa72e09eba..c1f48326fa 100644
[ -n "$vlan_tagged_interface" ] && \
append bss_conf "vlan_tagged_interface=$vlan_tagged_interface" "$N"
[ -n "$vlan_file" ] && {
@@ -882,6 +950,7 @@ hostapd_set_bss_options() {
@@ -882,6 +962,7 @@ hostapd_set_bss_options() {
json_get_vars iw_hessid iw_venue_group iw_venue_type iw_network_auth_type
json_get_vars iw_roaming_consortium iw_domain_name iw_anqp_3gpp_cell_net iw_nai_realm
json_get_vars iw_anqp_elem iw_qos_map_set iw_ipaddr_type_availability iw_gas_address3
@@ -503,7 +552,12 @@ index aa72e09eba..c1f48326fa 100644
set_default iw_enabled 0
if [ "$iw_enabled" = "1" ]; then
@@ -910,6 +979,8 @@ hostapd_set_bss_options() {
@@ -905,11 +986,12 @@ hostapd_set_bss_options() {
[ -n "$iw_network_auth_type" ] && \
append bss_conf "network_auth_type=$iw_network_auth_type" "$N"
[ -n "$iw_gas_address3" ] && append bss_conf "gas_address3=$iw_gas_address3" "$N"
- [ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N"
json_for_each_item append_iw_roaming_consortium iw_roaming_consortium
json_for_each_item append_iw_anqp_elem iw_anqp_elem
json_for_each_item append_iw_nai_realm iw_nai_realm
@@ -512,7 +566,11 @@ index aa72e09eba..c1f48326fa 100644
iw_domain_name_conf=
json_for_each_item append_iw_domain_name iw_domain_name
@@ -924,11 +995,14 @@ hostapd_set_bss_options() {
@@ -921,14 +1003,18 @@ hostapd_set_bss_options() {
[ -n "$iw_anqp_3gpp_cell_net_conf" ] && \
append bss_conf "anqp_3gpp_cell_net=$iw_anqp_3gpp_cell_net_conf" "$N"
fi
+ [ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N"
local hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \
@@ -529,7 +587,7 @@ index aa72e09eba..c1f48326fa 100644
set_default disable_dgaf $hs20
set_default osen 0
set_default anqp_domain_id 0
@@ -936,6 +1010,7 @@ hostapd_set_bss_options() {
@@ -936,6 +1022,7 @@ hostapd_set_bss_options() {
if [ "$hs20" = "1" ]; then
append bss_conf "hs20=1" "$N"
append_hs20_icons
@@ -537,7 +595,7 @@ index aa72e09eba..c1f48326fa 100644
append bss_conf "disable_dgaf=$disable_dgaf" "$N"
append bss_conf "osen=$osen" "$N"
append bss_conf "anqp_domain_id=$anqp_domain_id" "$N"
@@ -945,16 +1020,31 @@ hostapd_set_bss_options() {
@@ -945,16 +1032,31 @@ hostapd_set_bss_options() {
[ -n "$hs20_operating_class" ] && append bss_conf "hs20_operating_class=$hs20_operating_class" "$N"
[ -n "$hs20_t_c_filename" ] && append bss_conf "hs20_t_c_filename=$hs20_t_c_filename" "$N"
[ -n "$hs20_t_c_timestamp" ] && append bss_conf "hs20_t_c_timestamp=$hs20_t_c_timestamp" "$N"
@@ -570,7 +628,7 @@ index aa72e09eba..c1f48326fa 100644
set_default per_sta_vif 0
if [ "$per_sta_vif" -gt 0 ]; then
@@ -1079,16 +1169,16 @@ wpa_supplicant_set_fixed_freq() {
@@ -1079,16 +1181,16 @@ wpa_supplicant_set_fixed_freq() {
append network_data "frequency=$freq" "$N$T"
case "$htmode" in
NOHT) append network_data "disable_ht=1" "$N$T";;
@@ -591,7 +649,7 @@ index aa72e09eba..c1f48326fa 100644
*) append network_data "disable_vht=1" "$N$T";;
esac
}
@@ -1106,7 +1196,8 @@ wpa_supplicant_add_network() {
@@ -1106,19 +1208,21 @@ wpa_supplicant_add_network() {
ssid bssid key \
basic_rate mcast_rate \
ieee80211w ieee80211r \
@@ -600,8 +658,15 @@ index aa72e09eba..c1f48326fa 100644
+ default_disabled
case "$auth_type" in
sae|owe|eap192|eap-eap192)
@@ -1119,6 +1210,7 @@ wpa_supplicant_add_network() {
- sae|owe|eap192|eap-eap192)
+ sae|owe|eap-eap256)
set_default ieee80211w 2
;;
- psk-sae)
+ psk-sae|eap192|eap256)
set_default ieee80211w 1
;;
esac
set_default ieee80211r 0
set_default multi_ap 0
@@ -609,7 +674,7 @@ index aa72e09eba..c1f48326fa 100644
local key_mgmt='NONE'
local network_data=
@@ -1150,7 +1242,10 @@ wpa_supplicant_add_network() {
@@ -1150,7 +1254,10 @@ wpa_supplicant_add_network() {
scan_ssid=""
}
@@ -621,6 +686,15 @@ index aa72e09eba..c1f48326fa 100644
case "$auth_type" in
none) ;;
@@ -1186,7 +1293,7 @@ wpa_supplicant_add_network() {
fi
append network_data "$passphrase" "$N$T"
;;
- eap|eap192|eap-eap192)
+ eap|eap192|eap-eap256|eap256)
hostapd_append_wpa_key_mgmt
key_mgmt="$wpa_key_mgmt"
diff --git a/package/network/services/hostapd/patches/001-HE-VHT-fix-frequency-setup-with-HE-enabled.patch b/package/network/services/hostapd/patches/001-HE-VHT-fix-frequency-setup-with-HE-enabled.patch
deleted file mode 100644
index 37c17c50af..0000000000
@@ -5122,6 +5196,38 @@ index 0000000000..73db32e54a
+ } else if (os_strcmp(buf, "per_sta_vif") == 0) {
+ bss->ssid.per_sta_vif = atoi(pos);
+ } else if (os_strcmp(buf, "vlan_file") == 0) {
diff --git a/package/network/services/hostapd/patches/711-wds_bridge_force.patch b/package/network/services/hostapd/patches/711-wds_bridge_force.patch
new file mode 100644
index 0000000000..76a3547805
--- /dev/null
+++ b/package/network/services/hostapd/patches/711-wds_bridge_force.patch
@@ -0,0 +1,26 @@
+Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c
+===================================================================
+--- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c
++++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c
+@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho
+ sizeof(conf->bss[0]->iface));
+ } else if (os_strcmp(buf, "bridge") == 0) {
+ os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
++ if (!bss->wds_bridge[0])
++ os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
+ } else if (os_strcmp(buf, "vlan_bridge") == 0) {
+ os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
+ } else if (os_strcmp(buf, "wds_bridge") == 0) {
+Index: hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c
+===================================================================
+--- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_drv_ops.c
++++ hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c
+@@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d
+ return -1;
+ if (hapd->conf->wds_bridge[0])
+ bridge = hapd->conf->wds_bridge;
+- else if (hapd->conf->bridge[0])
+- bridge = hapd->conf->bridge;
+ return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
+ bridge, ifname_wds);
+ }
diff --git a/package/network/services/hostapd/patches/720-ACS-fix-channel-100-frequency.patch b/package/network/services/hostapd/patches/720-ACS-fix-channel-100-frequency.patch
new file mode 100644
index 0000000000..3ef19e5298
@@ -5292,12 +5398,14 @@ index 0000000000..793e8e0194
+ if (!hapd->l2) {
diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch
new file mode 100644
index 0000000000..8d928f8505
index 0000000000..6e60cde844
--- /dev/null
+++ b/package/network/services/hostapd/patches/740-snoop_iface.patch
@@ -0,0 +1,66 @@
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
@@ -0,0 +1,72 @@
+Index: hostapd-2021-05-22-b102f19b/src/ap/ap_config.h
+===================================================================
+--- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_config.h
++++ hostapd-2021-05-22-b102f19b/src/ap/ap_config.h
+@@ -278,6 +278,7 @@ struct hostapd_bss_config {
+ char iface[IFNAMSIZ + 1];
+ char bridge[IFNAMSIZ + 1];
@@ -5306,8 +5414,10 @@ index 0000000000..8d928f8505
+ char vlan_bridge[IFNAMSIZ + 1];
+ char wds_bridge[IFNAMSIZ + 1];
+
+--- a/src/ap/x_snoop.c
++++ b/src/ap/x_snoop.c
+Index: hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c
+===================================================================
+--- hostapd-2021-05-22-b102f19b.orig/src/ap/x_snoop.c
++++ hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c
+@@ -31,14 +31,16 @@ int x_snoop_init(struct hostapd_data *ha
+ return -1;
+ }
@@ -5351,12 +5461,14 @@ index 0000000000..8d928f8505
+ if (l2 == NULL) {
+ wpa_printf(MSG_DEBUG,
+ "x_snoop: Failed to initialize L2 packet processing %s",
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho
+ sizeof(conf->bss[0]->iface));
+ } else if (os_strcmp(buf, "bridge") == 0) {
+Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c
+===================================================================
+--- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c
++++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c
+@@ -2359,6 +2359,8 @@ static int hostapd_config_fill(struct ho
+ os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
+ if (!bss->wds_bridge[0])
+ os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
++ } else if (os_strcmp(buf, "snoop_iface") == 0) {
++ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface));
+ } else if (os_strcmp(buf, "vlan_bridge") == 0) {

View File

@@ -0,0 +1,215 @@
From b912dcd063381438ad70f4a3326ff0ac1be7c3ea Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 26 Oct 2021 20:41:22 +0200
Subject: [PATCH] bpf-headers: add a package with kernel headers for ebpf
In order to genererate suitable kernel headers, a 5.10 kernel tree is
prepared with a default config for mips. The arch is forced to mips in
order to avoid issues with inline asm on various architectures in a way
that doesn't involve relying on the host toolchain/headers.
It also has the advantage of supporting both endian types
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
include/bpf.mk | 60 +++++++++++
package/kernel/bpf-headers/Makefile | 99 +++++++++++++++++++
.../src/include/generated/bounds.h | 14 +++
3 files changed, 173 insertions(+)
create mode 100644 include/bpf.mk
create mode 100644 package/kernel/bpf-headers/Makefile
create mode 100644 package/kernel/bpf-headers/src/include/generated/bounds.h
diff --git a/include/bpf.mk b/include/bpf.mk
new file mode 100644
index 0000000000..4e227a11d0
--- /dev/null
+++ b/include/bpf.mk
@@ -0,0 +1,60 @@
+ifeq ($(CONFIG_BUILD_LLVM_BPF),)
+export PATH:=/usr/local/opt/llvm/bin:$(PATH)
+CLANG:=$(firstword $(shell PATH='$(PATH)' which clang clang-13 clang-12 clang-11 clang-10 clang-9))
+LLVM_VER:=$(subst clang,,$(notdir $(CLANG)))
+else
+CLANG:=$(STAGING_DIR_HOST)/bin/clang
+LLVM_VER:=
+endif
+
+LLVM_PATH:=$(dir $(CLANG))
+LLVM_LLC:=$(LLVM_PATH)/llc$(LLVM_VER)
+LLVM_DIS:=$(LLVM_PATH)/llvm-dis$(LLVM_VER)
+LLVM_OPT:=$(LLVM_PATH)/opt$(LLVM_VER)
+LLVM_STRIP:=$(LLVM_PATH)/llvm-strip$(LLVM_VER)
+
+BPF_KARCH:=mips
+BPF_ARCH:=mips$(if $(CONFIG_BIG_ENDIAN),,el)
+
+BPF_HEADERS_DIR:=$(STAGING_DIR)/bpf-headers
+
+BPF_KERNEL_INCLUDE := \
+ -nostdinc -isystem $(TOOLCHAIN_DIR)/include \
+ -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include \
+ -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/asm/mach-generic \
+ -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/generated \
+ -I$(BPF_HEADERS_DIR)/include \
+ -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/uapi \
+ -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/generated/uapi \
+ -I$(BPF_HEADERS_DIR)/include/uapi \
+ -I$(BPF_HEADERS_DIR)/include/generated/uapi \
+ -I$(BPF_HEADERS_DIR)/tools/lib \
+ -I$(BPF_HEADERS_DIR)/tools/testing/selftests \
+ -I$(BPF_HEADERS_DIR)/samples/bpf \
+ -include linux/kconfig.h -include asm_goto_workaround.h
+
+BPF_CFLAGS := \
+ $(BPF_KERNEL_INCLUDE) -I$(PKG_BUILD_DIR) \
+ -D__KERNEL__ -D__BPF_TRACING__ \
+ -D__TARGET_ARCH_${BPF_KARCH} \
+ -m$(if $(CONFIG_BIG_ENDIAN),big,little)-endian \
+ -fno-stack-protector -Wall \
+ -Wno-unused-value -Wno-pointer-sign \
+ -Wno-compare-distinct-pointer-types \
+ -Wno-gnu-variable-sized-type-not-at-end \
+ -Wno-address-of-packed-member -Wno-tautological-compare \
+ -Wno-unknown-warning-option \
+ -fno-asynchronous-unwind-tables \
+ -Wno-uninitialized -Wno-unused-variable \
+ -Wno-unused-label \
+ -O2 -emit-llvm -Xclang -disable-llvm-passes
+
+define CompileBPF
+ $(CLANG) -g -target $(BPF_ARCH)-linux-gnu $(BPF_CFLAGS) $(2) \
+ -c $(1) -o $(patsubst %.c,%.bc,$(1))
+ $(LLVM_OPT) -O2 -mtriple=bpf-pc-linux < $(patsubst %.c,%.bc,$(1)) > $(patsubst %.c,%.opt,$(1))
+ $(LLVM_DIS) < $(patsubst %.c,%.opt,$(1)) > $(patsubst %.c,%.S,$(1))
+ $(LLVM_LLC) -march=bpf -filetype=obj -o $(patsubst %.c,%.o,$(1)) < $(patsubst %.c,%.S,$(1))
+ $(LLVM_STRIP) --strip-debug $(patsubst %.c,%.o,$(1))
+endef
+
diff --git a/package/kernel/bpf-headers/Makefile b/package/kernel/bpf-headers/Makefile
new file mode 100644
index 0000000000..e316feea55
--- /dev/null
+++ b/package/kernel/bpf-headers/Makefile
@@ -0,0 +1,99 @@
+#
+# Copyright (C) 2006-2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+override QUILT:=
+override HOST_QUILT:=
+
+include $(INCLUDE_DIR)/kernel.mk
+
+
+PKG_NAME:=linux
+PKG_PATCHVER:=5.10
+PKG_VERSION:=$(PKG_PATCHVER)$(strip $(LINUX_VERSION-$(PKG_PATCHVER)))
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=$(LINUX_SITE)
+PKG_HASH:=$(LINUX_KERNEL_HASH-$(strip $(PKG_VERSION)))
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/bpf-headers/$(PKG_NAME)-$(PKG_VERSION)
+
+GENERIC_BACKPORT_DIR := $(GENERIC_PLATFORM_DIR)/backport$(if $(wildcard $(GENERIC_PLATFORM_DIR)/backport-$(PKG_PATCHVER)),-$(PKG_PATCHVER))
+GENERIC_PATCH_DIR := $(GENERIC_PLATFORM_DIR)/pending$(if $(wildcard $(GENERIC_PLATFORM_DIR)/pending-$(PKG_PATCHVER)),-$(PKG_PATCHVER))
+GENERIC_HACK_DIR := $(GENERIC_PLATFORM_DIR)/hack$(if $(wildcard $(GENERIC_PLATFORM_DIR)/hack-$(PKG_PATCHVER)),-$(PKG_PATCHVER))
+GENERIC_FILES_DIR := $(foreach dir,$(wildcard $(GENERIC_PLATFORM_DIR)/files $(GENERIC_PLATFORM_DIR)/files-$(PKG_PATCHVER)),"$(dir)")
+PATCH_DIR := $(CURDIR)/patches
+FILES_DIR :=
+
+REAL_LINUX_DIR := $(LINUX_DIR)
+LINUX_DIR := $(PKG_BUILD_DIR)
+
+include $(INCLUDE_DIR)/bpf.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bpf-headers
+ SECTION:=kernel
+ CATEGORY:=Kernel
+ TITLE:=eBPF kernel headers
+ BUILDONLY:=1
+ HIDDEN:=1
+endef
+
+export HOST_EXTRACFLAGS=-I$(STAGING_DIR_HOST)/include
+
+KERNEL_MAKE := \
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ ARCH=$(BPF_KARCH) \
+ CROSS_COMPILE=$(BPF_ARCH)-linux- \
+ LLVM=1 CC="$(CLANG)" LD="$(TARGET_CROSS)ld" \
+ HOSTCC="$(HOSTCC)" \
+ HOSTCXX="$(HOSTCXX)" \
+ HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib" \
+ KBUILD_HOSTLDLIBS="-L$(STAGING_DIR_HOST)/lib" \
+ CONFIG_SHELL="$(BASH)" \
+ INSTALL_HDR_PATH="$(PKG_BUILD_DIR)/user_headers"
+
+define Build/Patch
+ $(Kernel/Patch/Default)
+endef
+
+BPF_DOC = $(wildcard $(patsubst %,$(LINUX_DIR)/scripts/%.py,bpf_doc bpf_helpers_doc))
+
+define Build/Configure
+ grep -vE 'CONFIG_(CPU_.*ENDIAN|HZ)' $(PKG_BUILD_DIR)/arch/mips/configs/generic_defconfig > $(PKG_BUILD_DIR)/.config
+ echo 'CONFIG_CPU_$(if $(CONFIG_BIG_ENDIAN),BIG,LITTLE)_ENDIAN=y' >> $(PKG_BUILD_DIR)/.config
+ grep CONFIG_HZ $(REAL_LINUX_DIR)/.config >> $(PKG_BUILD_DIR)/.config
+ yes '' | $(KERNEL_MAKE) oldconfig
+ grep 'CONFIG_HZ=' $(REAL_LINUX_DIR)/.config | \
+ cut -d= -f2 | \
+ bc -q $(LINUX_DIR)/kernel/time/timeconst.bc \
+ > $(LINUX_DIR)/include/generated/timeconst.h
+ $(BPF_DOC) --header \
+ --file $(LINUX_DIR)/tools/include/uapi/linux/bpf.h \
+ > $(PKG_BUILD_DIR)/tools/lib/bpf/bpf_helper_defs.h
+endef
+
+define Build/Compile
+ $(KERNEL_MAKE) archprepare headers_install
+endef
+
+define Build/InstallDev
+ mkdir -p $(1)/bpf-headers/arch $(1)/bpf-headers/tools
+ $(CP) \
+ $(PKG_BUILD_DIR)/arch/$(BPF_KARCH) \
+ $(1)/bpf-headers/arch/
+ $(CP) \
+ $(PKG_BUILD_DIR)/tools/lib \
+ $(PKG_BUILD_DIR)/tools/testing \
+ $(1)/bpf-headers/tools/
+ $(CP) \
+ $(PKG_BUILD_DIR)/include \
+ $(PKG_BUILD_DIR)/samples \
+ $(PKG_BUILD_DIR)/scripts \
+ $(PKG_BUILD_DIR)/user_headers \
+ $(1)/bpf-headers
+endef
+
+$(eval $(call BuildPackage,bpf-headers))
diff --git a/package/kernel/bpf-headers/src/include/generated/bounds.h b/package/kernel/bpf-headers/src/include/generated/bounds.h
new file mode 100644
index 0000000000..82ff01043c
--- /dev/null
+++ b/package/kernel/bpf-headers/src/include/generated/bounds.h
@@ -0,0 +1,14 @@
+#ifndef __LINUX_BOUNDS_H__
+#define __LINUX_BOUNDS_H__
+/*
+ * DO NOT MODIFY.
+ *
+ * This file was generated by Kbuild
+ */
+
+#define NR_PAGEFLAGS 23 /* __NR_PAGEFLAGS */
+#define MAX_NR_ZONES 4 /* __MAX_NR_ZONES */
+#define NR_CPUS_BITS 1 /* ilog2(CONFIG_NR_CPUS) */
+#define SPINLOCK_SIZE 64 /* sizeof(spinlock_t) */
+
+#endif
--
2.25.1

View File

@@ -0,0 +1,47 @@
From 4b2e6bb352b400e244646a7bc59bc5ca3ca6f5df Mon Sep 17 00:00:00 2001
From: Roman Yeryomin <roman@advem.lv>
Date: Fri, 3 Sep 2021 17:31:11 +0300
Subject: [PATCH 32/32] iproute2: m_xt.so depends on dynsyms.list
When doing parallel build on a fast machine with bottleneck in i/o,
m_xt.so may start linking faster than dynsyms.list gets populated,
resulting in error:
ld:dynsyms.list:0: syntax error in dynamic list
Fix this by adding dynsyms.list as make dependency to m_xt.so
Described also here:
https://bugs.openwrt.org/index.php?do=details&task_id=3353
Change from v1:
- add dynsysms.list dependancy only when shared libs are enabled
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Fixes: FS#3353
---
.../utils/iproute2/patches/175-reduce-dynamic-syms.patch | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch b/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch
index da961a183b..c3892e5a0e 100644
--- a/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch
+++ b/package/network/utils/iproute2/patches/175-reduce-dynamic-syms.patch
@@ -26,13 +26,14 @@
q_atm.so: q_atm.c
$(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic -o q_atm.so q_atm.c -latm
-@@ -205,4 +206,15 @@ static-syms.h: $(wildcard *.c)
+@@ -205,4 +206,16 @@ static-syms.h: $(wildcard *.c)
sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
done > $@
+else
+
+tc: dynsyms.list
++m_xt.so: dynsyms.list
+dynsyms.list: $(wildcard *.c)
+ files="$(filter-out $(patsubst %.so,%.c,$(TCSO)), $^)" ; \
+ echo "{" > $@ ; \
--
2.25.1

View File

@@ -3,9 +3,9 @@ FROM ubuntu:20.04
RUN apt-get update \
&& DEBIAN_FRONTEND="noninteractive" apt-get -y install tzdata \
&& apt-get install -y \
time git-core build-essential gcc-multilib \
time git-core build-essential gcc-multilib clang \
libncurses5-dev zlib1g-dev gawk flex gettext wget unzip python \
python3 python3-pip python3-yaml libssl-dev rsync \
python3 python3-pip python3-yaml libssl-dev rsync llvm llvm-12 \
&& apt-get clean
RUN git config --global user.email "you@example.com"
RUN git config --global user.name "Your Name"

View File

@@ -24,8 +24,7 @@ define Package/fbwifi
SECTION:=net
CATEGORY:=Network
DEPENDS:=+iptables +luasec +luasocket \
+luci-base +libuci-lua +luaposix \
+luci-mod-network +luci-mod-status +luci-theme-bootstrap \
+libuci-lua +luaposix \
+lua-cjson +uhttpd
TITLE:=Facebook Wi-Fi
PKGARCH:=all
@@ -35,6 +34,22 @@ define Package/fbwifi/description
Facebook Wi-Fi, an AP authorisation solution
endef
define Package/luci-app-fbwifi
SUBMENU:=3. Applications
SECTION:=luci
CATEGORY:=LuCI
TITLE:=LuCI support for Facebook Wi-Fi
DEPENDS:= \
+fbwifi \
+luci-base +luci-mod-network +luci-mod-status +luci-theme-bootstrap
endef
define Package/luci-app-fbwifi/description
LuCI support for Facebook Wi-Fi
endef
define Package/fbwifi/conffiles
/etc/config/fbwifi
endef
@@ -50,7 +65,13 @@ endef
define Package/fbwifi/install
$(INSTALL_DIR) $(1)
$(CP) ./files/* $(1)/
$(CP) ./files/fbwifi/* $(1)/
endef
define Package/luci-app-fbwifi/install
$(INSTALL_DIR) $(1)
$(CP) ./files/luci-app-fbwifi/* $(1)
endef
$(eval $(call BuildPackage,fbwifi))
$(eval $(call BuildPackage,luci-app-fbwifi))

View File

@@ -11,48 +11,12 @@ To disable Facebook Wi-Fi, run `fbwifi disable`.
## Contents
The 'files' subdirectory contains all the configuration, script and code
that implements the Facebook Wi-Fi v2.0 standard for OpenWrt.
The 'files' subdirectory contains two subdirectories, one for the fbwifi
package that implements the Facebook Wi-Fi v2.0 standard for OpenWrt, and
another one containing a LuCI application to configure Facebook Wi-Fi.
The folder structure follows *nix conventions :
The folder structures follow *nix conventions:
- 'etc' is the boot time scripts and configuration
- 'usr' contains procedural scripts, lua common code module and GUI prototype for luci
- 'www' contains the HTTP endpoints as CGI handlers
```
files/
├── etc
│   ├── config
│   │   └── fbwifi
│   ├── hotplug.d
│   │   └── iface
│   │   └── 50-fbwifi
│   ├── init.d
│   │   └── fbwifi
├── usr
│   ├── lib
│   │   └── lua
│   │   ├── fbwifi.lua
│   │   └── luci
│   │   ├── controller
│   │   │   └── fbwifi.lua
│   │   └── view
│   │   └── fbwifi.htm
│   ├── sbin
│   │ ├── fbwifi
│   │ ├── fbwifi_debug_dump
│   │ ├── fbwifi_gateway_info_update
│   │ ├── fbwifi_get_config
│   │ └── fbwifi_validate_token_db
│ └── share
│ └── fbwifi
│ ├── firewall.include
│ └── uhttpd.json
└── www
└── cgi-bin
└── fbwifi
└── v2.0
├── auth
├── capport
└── info
```

View File

@@ -36,7 +36,7 @@ URL="https://api.fbwifi.com/v2.0/tokens"
BODY=string.format(
"tokens=%s&traffic_type=%s&config_version=%s",
json.encode(request.tokens),
"'total'",
"total",
state:get("fbwifi", "main", "config_version")
)

View File

@@ -17,7 +17,7 @@ include ./openvswitch.mk
#
PKG_NAME:=openvswitch
PKG_VERSION:=$(ovs_version)
PKG_RELEASE:=6
PKG_RELEASE:=9
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.openvswitch.org/releases/
PKG_HASH:=5c7baed537364d43af36c15dde298c95d35cb2cb3204b4d3fe9b0fc73c97f16d
@@ -155,7 +155,7 @@ ovs_libopenvswitch_title:=Open vSwitch (libopenvswitch.so)
ovs_libopenvswitch_hidden:=1
ovs_libopenvswitch_depends:=+libopenssl +!(arc||arceb):libunwind
ovs_libopenvswitch_depends+=+libatomic
ifeq ($(CONFIG_KEEPALIVED_ROUTES),y)
ifeq ($(CONFIG_OPENVSWITCH_WITH_LIBUNBOUND),y)
ovs_libopenvswitch_depends+=+libunbound
endif
ovs_libopenvswitch_files:=usr/lib/libopenvswitch*.so*

View File

@@ -85,12 +85,14 @@ after adding or changing these options.
The ovs_bridge section also supports the options below,
for initialising a virtual bridge with an OpenFlow controller.
| Name | Type | Required | Default | Description |
|-------------|---------|----------|--------------------------------|------------------------------------------------------------|
| disabled | boolean | no | 0 | If set to true, disable initialisation of the named bridge |
| name | string | no | Inherits UCI config block name | The name of the switch in the OVS daemon |
| controller | string | no | (none) | The endpoint of an OpenFlow controller for this bridge |
| datapath_id | string | no | (none) | The OpenFlow datapath ID for this bridge |
| Name | Type | Required | Default | Description |
|---------------|---------|----------|--------------------------------|------------------------------------------------------------|
| disabled | boolean | no | 0 | If set to true, disable initialisation of the named bridge |
| name | string | no | Inherits UCI config block name | The name of the switch in the OVS daemon |
| controller | string | no | (none) | The endpoint of an OpenFlow controller for this bridge |
| datapath_id | string | no | (none) | The OpenFlow datapath ID for this bridge |
| datapath_desc | string | no | (none) | The OpenFlow datapath description for this bridge |
| fail_mode | string | no | standalone | The bridge failure mode |
The ovs_port section can be used to add ports to a bridge. It supports the options below.

View File

@@ -14,7 +14,9 @@ config ovs_bridge
option disabled 1
option name 'my-bridge'
option controller 'tcp:192.168.0.1'
option datapath_desc ''
option datapath_id ''
option fail_mode 'standalone'
config ovs_port
option disabled 1

View File

@@ -187,6 +187,31 @@ ovs_bridge_validate_datapath_id() {
fi
}
ovs_bridge_validate_datapath_desc() {
local dpdesc="$1"
if [ "$(echo $dpdesc | wc -c)" -le 255 ]; then
return 0
else
logger -t openvswitch "invalid datapath_desc: $dpdesc"
return 1
fi
}
ovs_bridge_validate_fail_mode() {
local fail_mode="$1"
case "$fail_mode" in
secure|standalone)
return 0
;;
*)
logger -t openvswitch "invalid fail_mode: $fail_mode"
return 1
;;
esac
}
ovs_bridge_init() {
local cfg="$1"
@@ -208,6 +233,24 @@ ovs_bridge_init() {
}
}
config_get datapath_desc "$cfg" datapath_desc
[ -n "$datapath_desc" ] && {
ovs_bridge_validate_datapath_desc "$datapath_desc" && {
ovs-vsctl --if-exists set bridge "$name" other-config:dp-desc="$datapath_desc"
}
}
config_get fail_mode "$cfg" fail_mode
[ -n "$fail_mode" ] && {
ovs_bridge_validate_fail_mode "$fail_mode" && {
ovs-vsctl set-fail-mode "$name" "$fail_mode" 2> /dev/null
} || {
ovs-vsctl del-fail-mode "$name" 2> /dev/null
}
} || {
ovs-vsctl del-fail-mode "$name" 2> /dev/null
}
config_list_foreach "$cfg" "ports" ovs_bridge_port_add
config_foreach ovs_bridge_port_add_complex ovs_port "$name"
config_get_bool drop "$cfg" "drop_unknown_ports" 0

View File

@@ -21,3 +21,4 @@ config chilli
option kname 'chilli'
option debug 0
EOF
/etc/init.d/chilli disable

View File

@@ -22,6 +22,7 @@ let keys = {
nasmac: false,
macauth: false,
macpassword: false,
uamsecret: false,
};
function get_value(key, value) {

View File

@@ -2,6 +2,6 @@
[ "$ACTION" == "ifup" ] || exit 0
[ "$INTERFACE" = "wan" ] && {
[ "$INTERFACE" = "wan" -a "$(uci get chilli.@chilli[-1].disabled)" -neq 0 ] && {
/etc/init.d/chilli restart
}

View File

@@ -9,13 +9,16 @@ boot() {
local mtd=$(find_mtd_index certificates)
[ -n "$mtd" -a -f /sys/class/mtd/mtd$mtd/oobsize ] && ubiattach -p /dev/mtd$mtd
if [ -n "$(ubinfo -a | grep certificates)" ]; then
mount -t ubifs ubi0:certificates /certificates
mount -t ubifs ubi1:certificates /certificates
[ -e /dev/ubi0 ] && mount -t ubifs ubi0:certificates /certificates
[ -e /dev/ubi1 ] && mount -t ubifs ubi1:certificates /certificates
else
mount -t squashfs /dev/mtdblock$mtd /certificates
fi
[ -f /certificates/dev-id ] && {
cp /certificates/*.pem /etc/ucentral/
cp /certificates/dev-id /etc/ucentral/
chown root.network /etc/ucentral/*.pem
chmod 0440 root.network /etc/ucentral/*.pem
chmod 0400 /etc/ucentral/dev-id
}
}

View File

@@ -0,0 +1,17 @@
#
# Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI uCentral Configuration
LUCI_DEPENDS:=+luci-base
PKG_LICENSE:=Apache-2.0
include ../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@@ -0,0 +1,98 @@
'use strict';
'require fs';
'require ui';
'require dom';
'require rpc';
'require session';
'require baseclass';
var callReboot = rpc.declare({
object: 'system',
method: 'reboot',
expect: { result: 0 }
});
function handleReboot(ev) {
return callReboot().then(function(res) {
if (res != 0) {
showError(_('The reboot command failed with code %d').format(res));
L.raise('Error', 'Reboot failed');
}
showProgress(_('The system is rebooting in order to attempt applying the remote configuration profile now. If not successful, the device will revert back into the initial provisioning state.'));
ui.awaitReconnect();
}).catch(function(e) { showError(e.message) });
}
function setDirty(isDirty) {
if (isDirty) {
session.setLocalData('ucentral-dirty', true);
ui.showIndicator('ucentral-dirty', _('Reboot required'), showApplySettings);
}
else {
session.setLocalData('ucentral-dirty', null);
ui.hideIndicator('ucentral-dirty');
}
}
function handleContinue(ev) {
setDirty(true);
ui.hideModal();
}
function showApplySettings() {
ui.showModal(_('Apply Settings'), [
E('p', _('The device must be rebooted in order to apply the changed settings. Once the uCentral agent successfully connects to the controller, the remote configuration profile will be applied and the initial provisioning web interface is disabled.')),
E('div', { 'class': 'right' }, [
E('button', { 'click': handleReboot, 'class': 'btn primary' }, [ _('Apply settings and reboot device now') ]),
'\xa0',
E('button', { 'click': handleContinue, 'class': 'btn' }, [ _('Continue configuration') ])
])
]);
}
function showProgress(text, timeout) {
var dlg = ui.showModal(null, [
E('p', { 'class': (timeout > 0) ? null : 'spinning' }, text)
]);
dlg.removeChild(dlg.firstElementChild);
if (timeout > 0)
window.setTimeout(ui.hideModal, timeout);
return dlg;
}
function showError(text) {
ui.showModal(_('Error'), [
E('p', [ text ]),
E('div', { 'class': 'right' }, [
E('button', { 'class': 'btn', 'click': ui.hideModal }, _('OK'))
])
]);
}
if (session.getLocalData('ucentral-dirty'))
setDirty(true);
return baseclass.extend({
save: function(serializeFn, ev) {
var m = dom.findClassInstance(document.querySelector('.cbi-map'));
return m.save().then(function() {
return fs.write('/etc/ucentral/profile.json', serializeFn(m.data.data));
}).then(function() {
return fs.exec('/sbin/profileupdate');
}).then(function() {
showApplySettings();
}).catch(function(err) {
showError(_('Unable to save settings: %s').format(err));
});
},
setDirty: setDirty,
showError: showError,
showProgress: showProgress,
});

View File

@@ -0,0 +1,70 @@
'use strict';
'require view';
'require form';
'require fs';
'require ui';
'require tools.ucentral as uctool';
var profile = null;
function serialize(data) {
if (!L.isObject(profile.unit))
profile.unit = {};
profile.redirector = data.local.redirector;
profile.unit.location = data.local.location;
return JSON.stringify(profile, null, '\t');
}
return view.extend({
load: function() {
return L.resolveDefault(fs.read('/etc/ucentral/profile.json'), '').then(function(data) {
try { profile = JSON.parse(data); }
catch(e) { profile = {}; };
});
},
render: function() {
var m, s, o, data = { local: {
redirector: profile.redirector,
location: L.isObject(profile.unit) ? profile.unit.location : ''
} };
m = new form.JSONMap(data);
m.readonly = !L.hasViewPermission();
s = m.section(form.NamedSection, 'local', 'local', _('Local settings'),
_('The settings on this page specify how the local uCentral client connects to the controller server.'));
s.option(form.Value, 'redirector', _('Redirector URL'));
s.option(form.Value, 'location', _('Unit location'));
o = s.option(form.Button, '_certs', _('Certificates'));
o.inputtitle = _('Upload certificate bundle…');
o.onclick = function(ev) {
return ui.uploadFile('/tmp/certs.tar').then(function(res) {
uctool.showProgress(_('Verifying certificates…'));
return fs.exec('/sbin/certupdate').then(function(res) {
if (res.code) {
uctool.showError(_('Certificate validation failed: %s').format(res.stderr || res.stdout));
}
else {
uctool.showProgress(_('Certificates updated.'), 1500);
uctool.setDirty(true);
}
}, function(err) {
uctool.showError(_('Unable to verify certificates: %s').format(err));
});
});
};
return m.render();
},
handleSave: uctool.save.bind(uctool, serialize),
handleSaveApply: null,
handleReset: null
});

View File

@@ -0,0 +1,121 @@
'use strict';
'require rpc';
'require view';
'require tools.ucentral as uctool';
var callSystemBoard = rpc.declare({
object: 'system',
method: 'board'
});
var callSystemInfo = rpc.declare({
object: 'system',
method: 'info'
});
function progressbar(value, max, byte) {
var vn = parseInt(value) || 0,
mn = parseInt(max) || 100,
fv = byte ? String.format('%1024.2mB', value) : value,
fm = byte ? String.format('%1024.2mB', max) : max,
pc = Math.floor((100 / mn) * vn);
return E('div', {
'class': 'cbi-progressbar',
'title': '%s / %s (%d%%)'.format(fv, fm, pc)
}, E('div', { 'style': 'width:%.2f%%'.format(pc) }));
}
return view.extend({
load: function() {
return Promise.all([
L.resolveDefault(callSystemBoard(), {}),
L.resolveDefault(callSystemInfo(), {})
]);
},
render: function(data) {
var boardinfo = data[0],
systeminfo = data[1],
mem = L.isObject(systeminfo.memory) ? systeminfo.memory : {},
swap = L.isObject(systeminfo.swap) ? systeminfo.swap : {},
datestr = null;
if (systeminfo.localtime) {
var date = new Date(systeminfo.localtime * 1000);
datestr = '%04d-%02d-%02d %02d:%02d:%02d'.format(
date.getUTCFullYear(),
date.getUTCMonth() + 1,
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds()
);
}
var sysfields = [
_('Hostname'), boardinfo.hostname,
_('Model'), boardinfo.model,
_('Architecture'), boardinfo.system,
_('Firmware Version'), (L.isObject(boardinfo.release) ? boardinfo.release.description : '?'),
_('Kernel Version'), boardinfo.kernel,
_('Local Time'), datestr,
_('Uptime'), systeminfo.uptime ? '%t'.format(systeminfo.uptime) : null,
_('Load Average'), Array.isArray(systeminfo.load) ? '%.2f, %.2f, %.2f'.format(
systeminfo.load[0] / 65535.0,
systeminfo.load[1] / 65535.0,
systeminfo.load[2] / 65535.0
) : null
];
var systable = E('table', { 'class': 'table' });
for (var i = 0; i < sysfields.length; i += 2) {
systable.appendChild(E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td left', 'width': '33%' }, [ sysfields[i] ]),
E('td', { 'class': 'td left' }, [ (sysfields[i + 1] != null) ? sysfields[i + 1] : '?' ])
]));
}
var memfields = [
_('Total Available'), (mem.available) ? mem.available : (mem.total && mem.free && mem.buffered) ? mem.free + mem.buffered : null, mem.total,
_('Used'), (mem.total && mem.free) ? (mem.total - mem.free) : null, mem.total,
_('Buffered'), (mem.total && mem.buffered) ? mem.buffered : null, mem.total
];
if (mem.cached)
memfields.push(_('Cached'), mem.cached, mem.total);
if (swap.total > 0)
memfields.push(_('Swap free'), swap.free, swap.total);
var memtable = E('table', { 'class': 'table' });
for (var i = 0; i < memfields.length; i += 3) {
memtable.appendChild(E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td left', 'width': '33%' }, [ memfields[i] ]),
E('td', { 'class': 'td left' }, [
(memfields[i + 1] != null) ? progressbar(memfields[i + 1], memfields[i + 2], true) : '?'
])
]));
}
return E([], [
E('div', { 'class': 'cbi-section' }, [
E('h3', _('System')),
systable
]),
E('div', { 'class': 'cbi-section' }, [
E('h3', _('Memory')),
memtable
]),
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});

View File

@@ -0,0 +1,180 @@
'use strict';
'require view';
'require dom';
'require form';
'require rpc';
'require fs';
'require ui';
'require tools.ucentral as uctool';
var callSystemValidateFirmwareImage = rpc.declare({
object: 'system',
method: 'validate_firmware_image',
params: [ 'path' ],
expect: { '': { valid: false, forcable: true } }
});
var callReboot = rpc.declare({
object: 'system',
method: 'reboot',
expect: { result: 0 }
});
var mapdata = { actions: {}, config: {} };
return view.extend({
load: function() {
var tasks = [
fs.trimmed('/proc/mtd'),
fs.trimmed('/proc/mounts')
];
return Promise.all(tasks);
},
handleFirstboot: function(ev) {
if (!confirm(_('Do you really want to erase all settings?')))
return;
uctool.showProgress(_('The system is erasing the configuration partition now and will reboot itself when finished.'));
/* Currently the sysupgrade rpc call will not return, hence no promise handling */
fs.exec('/sbin/firstboot', [ '-r', '-y' ]);
ui.awaitReconnect('192.168.1.1', 'openwrt.lan');
},
handleSysupgrade: function(ev) {
return ui.uploadFile('/tmp/firmware.bin', ev.target.firstChild)
.then(L.bind(function(btn, reply) {
btn.firstChild.data = _('Checking image…');
uctool.showProgress(_('Verifying the uploaded image file.'));
return callSystemValidateFirmwareImage('/tmp/firmware.bin')
.then(function(res) { return [ reply, res ]; });
}, this, ev.target))
.then(L.bind(function(btn, reply) {
return fs.exec('/sbin/sysupgrade', [ '--test', '/tmp/firmware.bin' ])
.then(function(res) { reply.push(res); return reply; });
}, this, ev.target))
.then(L.bind(function(btn, res) {
var is_valid = res[1].valid,
body = [];
if (is_valid) {
body.push(E('p', _("The firmware image was uploaded. Compare the checksum and file size listed below with the original file to ensure data integrity. <br /> Click 'Continue' below to start the flash procedure.")));
body.push(E('ul', {}, [
res[0].size ? E('li', {}, '%s: %1024.2mB'.format(_('Size'), res[0].size)) : '',
res[0].checksum ? E('li', {}, '%s: %s'.format(_('MD5'), res[0].checksum)) : '',
res[0].sha256sum ? E('li', {}, '%s: %s'.format(_('SHA256'), res[0].sha256sum)) : ''
]));
}
else {
body.push(E('p', _("The firmware image is invalid and cannot be flashed. Check the diagnostics below for further details.")));
if (res[2].stderr)
body.push(E('pre', { 'class': 'alert-message' }, [ res[2].stderr ]));
}
var cntbtn = E('button', {
'class': 'btn cbi-button-action important',
'click': ui.createHandlerFn(this, 'handleSysupgradeConfirm', btn),
'disabled': !is_valid
}, [ _('Continue') ]);
body.push(E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn',
'click': ui.createHandlerFn(this, function(ev) {
return fs.remove('/tmp/firmware.bin').finally(ui.hideModal);
})
}, [ _('Cancel') ]), ' ', cntbtn
]));
ui.showModal(is_valid ? _('Flash image?') : _('Invalid image'), body);
}, this, ev.target))
.catch(function(e) { uctool.showError(e.message) })
.finally(L.bind(function(btn) {
btn.firstChild.data = _('Flash image…');
}, this, ev.target));
},
handleSysupgradeConfirm: function(btn, ev) {
btn.firstChild.data = _('Flashing…');
uctool.showProgress(_('The system is flashing now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings.'));
/* Currently the sysupgrade rpc call will not return, hence no promise handling */
fs.exec('/sbin/sysupgrade', [ '-n', '/tmp/firmware.bin' ]);
ui.awaitReconnect('192.168.1.1', 'openwrt.lan');
},
handleReboot: function(ev) {
return callReboot().then(function(res) {
if (res != 0) {
uctool.showError(_('The reboot command failed with code %d').format(res));
L.raise('Error', 'Reboot failed');
}
uctool.showProgress(_('The device is rebooting now. This page will try to reconnect automatically once the device is fully booted.'));
ui.awaitReconnect();
})
.catch(function(e) { uctool.showError(e.message) });
},
render: function(rpc_replies) {
var procmtd = rpc_replies[0],
procmounts = rpc_replies[1],
has_rootfs_data = (procmtd.match(/"rootfs_data"/) != null) || (procmounts.match("overlayfs:\/overlay \/ ") != null),
m, s, o, ss;
m = new form.JSONMap(mapdata);
m.readonly = !L.hasViewPermission();
s = m.section(form.NamedSection, 'actions');
o = s.option(form.SectionValue, 'actions', form.NamedSection, 'actions', 'actions', _('Reboot device'),
_('Issue a reboot and restart the operating system on this device.'));
ss = o.subsection;
o = ss.option(form.Button, 'reboot');
o.inputstyle = 'action important';
o.inputtitle = _('Reboot');
o.onclick = L.bind(this.handleReboot, this);
o = s.option(form.SectionValue, 'actions', form.NamedSection, 'actions', 'actions', _('Reset to defaults'),
_('Reset the system to its initial state and discard any configuration changes.'));
ss = o.subsection;
if (has_rootfs_data) {
o = ss.option(form.Button, 'reset');
o.inputstyle = 'negative important';
o.inputtitle = _('Perform reset');
o.onclick = this.handleFirstboot;
}
o = s.option(form.SectionValue, 'actions', form.NamedSection, 'actions', 'actions', _('Firmware upgrade'),
_('Upload a compatible firmware image here to upgrade the running system.'));
ss = o.subsection;
o = ss.option(form.Button, 'sysupgrade');
o.inputstyle = 'action important';
o.inputtitle = _('Flash image…');
o.onclick = L.bind(this.handleSysupgrade, this);
return m.render();
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});

View File

@@ -0,0 +1,118 @@
'use strict';
'require view';
'require form';
'require fs';
'require tools.ucentral as uctool';
var profile = null;
function serialize(data) {
if (data.broadband.protocol != 'default')
profile.broadband = Object.assign({}, data.broadband);
else
delete profile.broadband;
return JSON.stringify(profile, function(key, val) {
return (key.charAt(0) != '.') ? val : undefined;
}, '\t');
}
return view.extend({
load: function() {
return L.resolveDefault(fs.read('/etc/ucentral/profile.json'), '').then(function(data) {
try { profile = JSON.parse(data); }
catch(e) { profile = {}; };
if (!L.isObject(profile.broadband))
profile.broadband = { protocol: 'default' };
});
},
render: function() {
var m, s, o, data = { broadband: {} };
m = new form.JSONMap(data);
m.readonly = !L.hasViewPermission();
s = m.section(form.NamedSection, 'broadband', 'broadband', _('Uplink configuration'),
_('The uplink settings allow overriding the WAN connection properties of the local device.'));
o = s.option(form.ListValue, 'protocol', _('Connection'));
o.value('default', _('Use default cloud settings'));
o.value('static', _('Static address configuration'));
o.value('dhcp', _('Address configuration via DHCP'));
o.value('pppoe', _('Address configuration via PPPoE'));
o.value('wwan', _('Cellular network connection'));
o = s.option(form.ListValue, 'modem-type', _('Modem type'));
o.depends('protocol', 'wwan');
o.value('wwan', _('Automatic', 'Automatic modem type selection'));
o.value('mbim', 'MBIM');
o.value('qmi', 'QMI');
o = s.option(form.Value, 'access-point-name', _('APN', 'Cellular access point name'));
o.depends('protocol', 'wwan');
o.validate = function(section_id, value) {
if (!/^[a-zA-Z0-9\-.]*[a-zA-Z0-9]$/.test(value))
return _('Invalid APN provided');
return true;
};
o = s.option(form.Value, 'pin-code', _('PIN'));
o.depends('protocol', 'wwan');
o.datatype = 'and(uinteger,minlength(4),maxlength(8))';
o = s.option(form.ListValue, 'authentication-type', _('Authentication'));
o.depends('protocol', 'wwan');
o.value('', _('No authentication'));
o.value('pap-chap', 'PAP/CHAP');
o.value('chap', 'CHAP');
o.value('pap', 'PAP');
o = s.option(form.Value, 'user-name', _('Username'));
o.depends('authentication-type', 'pap-chap');
o.depends('authentication-type', 'chap');
o.depends('authentication-type', 'pap');
o.depends('protocol', 'pppoe');
o = s.option(form.Value, 'password', _('Password'));
o.depends('authentication-type', 'pap-chap');
o.depends('authentication-type', 'chap');
o.depends('authentication-type', 'pap');
o.depends('protocol', 'pppoe');
o.password = true;
o = s.option(form.Value, 'ipv4-address', _('IPv4 Address'), _('Address and mask in CIDR notation.'));
o.depends('protocol', 'static');
o.datatype = 'or(cidr4,ipnet4)';
o.rmempty = false;
o = s.option(form.Value, 'ipv4-gateway', _('IPv4 Gateway'));
o.depends('protocol', 'static');
o.datatype = 'ip4addr("nomask")';
o.rmempty = false;
o = s.option(form.Value, 'ipv6-address', _('IPv6 Address'), _('Address and mask in CIDR notation.'));
o.depends('protocol', 'static');
o.datatype = 'or(cidr6,ipnet6)';
o = s.option(form.Value, 'ipv6-gateway', _('IPv6 Gateway'));
o.depends('protocol', 'static');
o.datatype = 'ip6addr("nomask")';
o = s.option(form.DynamicList, 'use-dns', _('DNS Servers'));
o.depends('protocol', 'static');
o.datatype = 'ipaddr("nomask")';
for (var i = 0; i < s.children.length; i++)
data.broadband[s.children[i].option] = profile.broadband[s.children[i].option];
return m.render();
},
handleSave: uctool.save.bind(uctool, serialize),
handleSaveApply: null,
handleReset: null
});

View File

@@ -0,0 +1,426 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: \n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"X-Generator: Poedit 2.4.2\n"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:53
msgctxt "Cellular access point name"
msgid "APN"
msgstr "APN"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:86
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:96
msgid "Address and mask in CIDR notation."
msgstr "Adresse und Netzmaske in CIDR-Notation."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:43
msgid "Address configuration via DHCP"
msgstr "Adresskonfiguration mittels DHCP"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:44
msgid "Address configuration via PPPoE"
msgstr "Adresskonfiguration mittels PPPoE"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:49
msgid "Apply Settings"
msgstr "Einstellungen anwenden"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:52
msgid "Apply settings and reboot device now"
msgstr "Anwenden und Gerät jetzt neu starten"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:60
msgid "Architecture"
msgstr "Architektur"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:66
msgid "Authentication"
msgstr "Authentifizierung"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:49
msgctxt "Automatic modem type selection"
msgid "Automatic"
msgstr "automatisch"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:85
msgid "Buffered"
msgstr "Gepuffert"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:89
msgid "Cached"
msgstr "Gecached"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:92
msgid "Cancel"
msgstr "Abbrechen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:45
msgid "Cellular network connection"
msgstr "Mobilfunkverbindung"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:51
msgid "Certificate validation failed: %s"
msgstr "Validierung der Zertifikate fehlgeschlagen: %s"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:43
msgid "Certificates"
msgstr "Zertifikate"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:54
msgid "Certificates updated."
msgstr "Zertifikate aktualisiert."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:51
msgid "Checking image…"
msgstr "Prüfe Imagedatei…"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:40
msgid "Connection"
msgstr "Verbindung"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:84
msgid "Continue"
msgstr "Fortfahren"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:54
msgid "Continue configuration"
msgstr "Konfiguration fortsetzen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:104
msgid "DNS Servers"
msgstr "DNS-Server"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:37
msgid "Do you really want to erase all settings?"
msgstr "Sollen wirklich alle Systemeinstellungen zurückgesetzt werden?"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:73
msgid "Error"
msgstr "Fehler"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:61
msgid "Firmware Version"
msgstr "Firmware-Version"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:163
msgid "Firmware upgrade"
msgstr "Firmware Update"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:95
msgid "Flash image?"
msgstr "Image flashen?"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:99
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:170
msgid "Flash image…"
msgstr "Image flashen…"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:104
msgid "Flashing…"
msgstr "Schreibt…"
#: modules/luci-mod-ucentral/root/usr/share/rpcd/acl.d/luci-mod-ucentral.json:3
msgid "Grant access to ucentral configuration"
msgstr "Zugriff auf uCentral-Konfigurationseinstellungen ermöglichen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:58
msgid "Hostname"
msgstr "Hostname"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:86
msgid "IPv4 Address"
msgstr "IPv4-Adresse"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:91
msgid "IPv4 Gateway"
msgstr "IPv4-Gateway"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:96
msgid "IPv6 Address"
msgstr "IPv6-Adresse"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:100
msgid "IPv6 Gateway"
msgstr "IPv6-Gateway"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:57
msgid "Invalid APN provided"
msgstr "Ungültige APN angegeben"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:95
msgid "Invalid image"
msgstr "Ungültige Image-Datei"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:141
msgid "Issue a reboot and restart the operating system on this device."
msgstr "Einen Reboot auslösen und das Betriebssystem des Gerätes neu starten."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:62
msgid "Kernel Version"
msgstr "Kernel-Version"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:65
msgid "Load Average"
msgstr "Systemlast"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:63
msgid "Local Time"
msgstr "Lokalzeit"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:37
msgid "Local settings"
msgstr "Lokale Einstellungen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:69
msgid "MD5"
msgstr "MD5"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:112
msgid "Memory"
msgstr "Arbeitsspeicher"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:59
msgid "Model"
msgstr "Modell"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:47
msgid "Modem type"
msgstr "Modemtyp"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:68
msgid "No authentication"
msgstr "keine Authentifizierung"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:76
msgid "OK"
msgstr "OK"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:62
msgid "PIN"
msgstr "OIN"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:79
msgid "Password"
msgstr "Passwort"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:158
msgid "Perform reset"
msgstr "System zurücksetzen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:147
msgid "Reboot"
msgstr "Reboot"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:140
msgid "Reboot device"
msgstr "Gerät neu starten"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:35
msgid "Reboot required"
msgstr "Neustart erforderlich"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:40
msgid "Redirector URL"
msgstr "Redirector-URL"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:152
msgid ""
"Reset the system to its initial state and discard any configuration changes."
msgstr ""
"Das System auf Grundeinstellungen zurücksetzen und sämtliche "
"Konfigurationsänderungen verwerfen."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:151
msgid "Reset to defaults"
msgstr "Grundeinstellungen wiederherstellen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:70
msgid "SHA256"
msgstr "SHA256"
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:40
msgid "Settings"
msgstr "Einstellungen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:68
msgid "Size"
msgstr "Größe"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:42
msgid "Static address configuration"
msgstr "Statische Adresskonfiguration"
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:16
msgid "Status"
msgstr "Status"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:92
msgid "Swap free"
msgstr "Freier Auslagerungsspeicher"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:108
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:52
msgid "System"
msgstr "System"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:121
msgid ""
"The device is rebooting now. This page will try to reconnect automatically "
"once the device is fully booted."
msgstr ""
"Das Gerät startet jetzt neu. Diese Seite wird versuchen sich automatisch neu "
"zu verbinden sobald das Gerät wieder voll hochgefahren ist."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:50
msgid ""
"The device must be rebooted in order to apply the changed settings. Once the "
"uCentral agent successfully connects to the controller, the remote "
"configuration profile will be applied and the initial provisioning web "
"interface is disabled."
msgstr ""
"Das Gerät muss neu gestartet werden um die geänderten Einstellungen "
"anzuwenden. Sobald sich der uCentral-Client nach dem Neustart erfolgreich "
"mit dem Controller verbindet, wird das entfernte Konfigurationsprofil für "
"dieses Gerät angewendet und das initiale Provisionierungs-Webinterface "
"deaktiviert."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:74
msgid ""
"The firmware image is invalid and cannot be flashed. Check the diagnostics "
"below for further details."
msgstr ""
"Die Firmware-Datei ist ungültig und kann nicht geflasht werden. Die "
"nachfolgenden Diagnosemeldungen enthalten weitere Details."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:66
msgid ""
"The firmware image was uploaded. Compare the checksum and file size listed "
"below with the original file to ensure data integrity. <br /> Click "
"'Continue' below to start the flash procedure."
msgstr ""
"Die Firmware-Datei wurde hochgeladen. Die Prüfsummen und Dateigröße mit der "
"Originaldatei vergleichen um die Integrität des Images sicherzustellen.<br /"
"> \"Fortfahren\" anklicken um die Upgrade-Prozedur zu starten."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:22
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:117
msgid "The reboot command failed with code %d"
msgstr "Das Reboot-Kommando wurde mit Fehlercode %d abgebrochen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:38
msgid ""
"The settings on this page specify how the local uCentral client connects to "
"the controller server."
msgstr ""
"Die Einstellungen auf dieser Seite beeinflussen die Verbindung des uCentral "
"Clients zum Controller-Server."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:40
msgid ""
"The system is erasing the configuration partition now and will reboot itself "
"when finished."
msgstr ""
"Das System löscht nun die Konfigurationspartition und startet das Gerät neu "
"sobald die Prozedur abgeschlossen ist."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:106
msgid ""
"The system is flashing now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a "
"few minutes before you try to reconnect. It might be necessary to renew the "
"address of your computer to reach the device again, depending on your "
"settings."
msgstr ""
"Das System-Upgrade läuft jetzt.<br />DAS GERÄT NICHT AUSSCHALTEN!<br /"
">Einige Minuten warten, bevor ein Verbindungsversuch unternommen wird. Ja "
"nach Netzwerktopologie kann es nötig sein, die lokalen Adresseinstellungen "
"des Computers zu verändern bevor wieder eine Verbindung zum Gerät möglich "
"ist."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:26
msgid ""
"The system is rebooting in order to attempt applying the remote "
"configuration profile now. If not successful, the device will revert back "
"into the initial provisioning state."
msgstr ""
"Das System startet jetzt neu um zu versuchen das entfernte "
"Konfigurationsprofil anzuwenden. Im Fehlerfall wird das Gerät in den "
"initialen Provisionierungs-Zustand zurückversetzt."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:38
msgid ""
"The uplink settings allow overriding the WAN connection properties of the "
"local device."
msgstr ""
"Die Uplink-Einstellungen ermöglichen es die WAN-Verbindungseigenschaften des "
"lokalen Gerätes zu überschreiben."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:83
msgid "Total Available"
msgstr "Gesamt verfügbar"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:95
msgid "Unable to save settings: %s"
msgstr "Einstellungen konnten nicht gespeichert werden: %s"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:58
msgid "Unable to verify certificates: %s"
msgstr "Zertifikate konnten nicht verifiziert werden: %s"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:41
msgid "Unit location"
msgstr "Gerätestandort"
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:28
msgid "Uplink"
msgstr "Uplink"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:37
msgid "Uplink configuration"
msgstr "Uplink-Einstellungen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:164
msgid "Upload a compatible firmware image here to upgrade the running system."
msgstr ""
"Kompatible Firmware-Datei hier hochladen um das laufende System zu "
"aktualisieren."
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:44
msgid "Upload certificate bundle…"
msgstr "Zertifikatsarchiv hochladen…"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:64
msgid "Uptime"
msgstr "Laufzeit"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:41
msgid "Use default cloud settings"
msgstr "Cloud-Einstellungen nutzen"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:84
msgid "Used"
msgstr "In Benutzung"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:73
msgid "Username"
msgstr "Benutzername"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:47
msgid "Verifying certificates…"
msgstr "Überprüfe Zertifikate…"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:52
msgid "Verifying the uploaded image file."
msgstr "Überprüfe die hochgeladene Image-Datei."
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:3
msgid "uCentral"
msgstr "uCentral"

View File

@@ -0,0 +1,385 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:53
msgctxt "Cellular access point name"
msgid "APN"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:86
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:96
msgid "Address and mask in CIDR notation."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:43
msgid "Address configuration via DHCP"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:44
msgid "Address configuration via PPPoE"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:49
msgid "Apply Settings"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:52
msgid "Apply settings and reboot device now"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:60
msgid "Architecture"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:66
msgid "Authentication"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:49
msgctxt "Automatic modem type selection"
msgid "Automatic"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:85
msgid "Buffered"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:89
msgid "Cached"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:92
msgid "Cancel"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:45
msgid "Cellular network connection"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:51
msgid "Certificate validation failed: %s"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:43
msgid "Certificates"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:54
msgid "Certificates updated."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:51
msgid "Checking image…"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:40
msgid "Connection"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:84
msgid "Continue"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:54
msgid "Continue configuration"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:104
msgid "DNS Servers"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:37
msgid "Do you really want to erase all settings?"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:73
msgid "Error"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:61
msgid "Firmware Version"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:163
msgid "Firmware upgrade"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:95
msgid "Flash image?"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:99
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:170
msgid "Flash image…"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:104
msgid "Flashing…"
msgstr ""
#: modules/luci-mod-ucentral/root/usr/share/rpcd/acl.d/luci-mod-ucentral.json:3
msgid "Grant access to ucentral configuration"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:58
msgid "Hostname"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:86
msgid "IPv4 Address"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:91
msgid "IPv4 Gateway"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:96
msgid "IPv6 Address"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:100
msgid "IPv6 Gateway"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:57
msgid "Invalid APN provided"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:95
msgid "Invalid image"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:141
msgid "Issue a reboot and restart the operating system on this device."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:62
msgid "Kernel Version"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:65
msgid "Load Average"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:63
msgid "Local Time"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:37
msgid "Local settings"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:69
msgid "MD5"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:112
msgid "Memory"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:59
msgid "Model"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:47
msgid "Modem type"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:68
msgid "No authentication"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:76
msgid "OK"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:62
msgid "PIN"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:79
msgid "Password"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:158
msgid "Perform reset"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:147
msgid "Reboot"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:140
msgid "Reboot device"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:35
msgid "Reboot required"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:40
msgid "Redirector URL"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:152
msgid ""
"Reset the system to its initial state and discard any configuration changes."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:151
msgid "Reset to defaults"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:70
msgid "SHA256"
msgstr ""
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:40
msgid "Settings"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:68
msgid "Size"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:42
msgid "Static address configuration"
msgstr ""
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:16
msgid "Status"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:92
msgid "Swap free"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:108
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:52
msgid "System"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:121
msgid ""
"The device is rebooting now. This page will try to reconnect automatically "
"once the device is fully booted."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:50
msgid ""
"The device must be rebooted in order to apply the changed settings. Once the "
"uCentral agent successfully connects to the controller, the remote "
"configuration profile will be applied and the initial provisioning web "
"interface is disabled."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:74
msgid ""
"The firmware image is invalid and cannot be flashed. Check the diagnostics "
"below for further details."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:66
msgid ""
"The firmware image was uploaded. Compare the checksum and file size listed "
"below with the original file to ensure data integrity. <br /> Click "
"'Continue' below to start the flash procedure."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:22
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:117
msgid "The reboot command failed with code %d"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:38
msgid ""
"The settings on this page specify how the local uCentral client connects to "
"the controller server."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:40
msgid ""
"The system is erasing the configuration partition now and will reboot itself "
"when finished."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:106
msgid ""
"The system is flashing now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a "
"few minutes before you try to reconnect. It might be necessary to renew the "
"address of your computer to reach the device again, depending on your "
"settings."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:26
msgid ""
"The system is rebooting in order to attempt applying the remote "
"configuration profile now. If not successful, the device will revert back "
"into the initial provisioning state."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:38
msgid ""
"The uplink settings allow overriding the WAN connection properties of the "
"local device."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:83
msgid "Total Available"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/tools/ucentral.js:95
msgid "Unable to save settings: %s"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:58
msgid "Unable to verify certificates: %s"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:41
msgid "Unit location"
msgstr ""
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:28
msgid "Uplink"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:37
msgid "Uplink configuration"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:164
msgid "Upload a compatible firmware image here to upgrade the running system."
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:44
msgid "Upload certificate bundle…"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:64
msgid "Uptime"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:41
msgid "Use default cloud settings"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/status.js:84
msgid "Used"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/uplink.js:73
msgid "Username"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/settings.js:47
msgid "Verifying certificates…"
msgstr ""
#: modules/luci-mod-ucentral/htdocs/luci-static/resources/view/ucentral/system.js:52
msgid "Verifying the uploaded image file."
msgstr ""
#: modules/luci-mod-ucentral/root/usr/share/luci/menu.d/luci-mod-ucentral.json:3
msgid "uCentral"
msgstr ""

View File

@@ -0,0 +1,33 @@
#!/bin/sh
# make sure we have a tar file
[ -f /tmp/certs.tar ] || exit 1
# check if there is a certificates partition
. /lib/functions.sh
mtd="$(find_mtd_index certificates)"
[ -z "$mtd" ] && exit 1
# check if this is ubi or squashfs
ubi="$(ubinfo -a | grep certificates)"
# extract the certificates
mkdir /tmp/certs
cd /tmp/certs
tar xf /tmp/certs.tar
# copy the certificates to /etc
cp *.pem dev-id /etc/ucentral/
# persistently store the certificates
if [ -z "$ubi" ]; then
# squashfs
mtd write /tmp/certs/squashfs /dev/mtd$mtd
else
# ubi
[ -e /dev/ubi0 ] && mount -t ubifs ubi0:certificates /certificates
[ -e /dev/ubi1 ] && mount -t ubifs ubi1:certificates /certificates
cp *.pem dev-id /certificates/
fi
exit 0

View File

@@ -0,0 +1,15 @@
#!/bin/sh
REDIRECTOR=$(cat /etc/ucentral/profile.json | jsonfilter -e '@.redirector')
if [ -n "$REDIRECTOR" ]; then
uci -c /etc/config-shadow/ set ucentral.config.server="$REDIRECTOR"
uci -c /etc/config-shadow/ commit ucentral
/etc/init.d/firstcontact disable
/etc/init.d/ucentral enable
else
rm /etc/ucentral/redirector.json
/etc/init.d/firstcontact enable
/etc/init.d/ucentral disable
fi
exit 0

View File

@@ -0,0 +1,62 @@
{
"ucentral": {
"title": "uCentral",
"order": 20,
"action": {
"type": "firstchild",
"recurse": true
},
"auth": {
"methods": [ "cookie:sysauth" ],
"login": true
}
},
"ucentral/status": {
"title": "Status",
"order": 1,
"action": {
"type": "view",
"path": "ucentral/status"
},
"depends": {
"acl": [ "luci-mod-ucentral" ]
}
},
"ucentral/uplink": {
"title": "Uplink",
"order": 2,
"action": {
"type": "view",
"path": "ucentral/uplink"
},
"depends": {
"acl": [ "luci-mod-ucentral" ]
}
},
"ucentral/settings": {
"title": "Settings",
"order": 3,
"action": {
"type": "view",
"path": "ucentral/settings"
},
"depends": {
"acl": [ "luci-mod-ucentral" ]
}
},
"ucentral/system": {
"title": "System",
"order": 4,
"action": {
"type": "view",
"path": "ucentral/system"
},
"depends": {
"acl": [ "luci-mod-ucentral" ]
}
}
}

View File

@@ -0,0 +1,33 @@
{
"luci-mod-ucentral": {
"description": "Grant access to ucentral configuration",
"read": {
"file": {
"/etc/ucentral/profile.json": [ "read" ],
"/proc/mounts": [ "read" ],
"/proc/mtd": [ "read" ]
},
"ubus": {
"file": [ "read" ],
"system": [ "board", "info" ]
}
},
"write": {
"cgi-io": [ "upload" ],
"file": {
"/etc/ucentral/profile.json": [ "write" ],
"/sbin/certupdate": [ "exec" ],
"/sbin/firstboot -r -y": [ "exec" ],
"/sbin/profileupdate": [ "exec" ],
"/sbin/sysupgrade -n /tmp/firmware.bin": [ "exec" ],
"/sbin/sysupgrade --test /tmp/firmware.bin": [ "exec" ],
"/tmp/certs.tar": [ "write" ],
"/tmp/firmware.bin": [ "write" ]
},
"ubus": {
"file": [ "exec", "remove", "write" ],
"system": [ "reboot", "validate_firmware_image" ]
}
}
}
}

View File

@@ -0,0 +1,14 @@
#
# Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI theme for uCentral
LUCI_DEPENDS:=
include ../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@@ -0,0 +1,152 @@
'use strict';
'require baseclass';
'require ui';
return baseclass.extend({
__init__: function() {
ui.menu.load().then(L.bind(this.render, this));
},
render: function(tree) {
var menu = document.querySelector('#mainmenu'),
nav = document.querySelector('#menubar > .navigation'),
node = tree,
url = '';
this.renderModeMenu(node);
if (L.env.dispatchpath.length >= 3) {
for (var i = 0; i < 3 && node; i++) {
node = node.children[L.env.dispatchpath[i]];
url = url + (url ? '/' : '') + L.env.dispatchpath[i];
}
if (node)
this.renderTabMenu(node, url);
}
if (menu.firstElementChild) {
nav.addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle'));
nav.style.visibility = 'visible';
}
},
handleMenuExpand: function(ev) {
var a = ev.target, ul1 = a.parentNode.parentNode, ul2 = a.nextElementSibling;
document.querySelectorAll('ul.mainmenu.l1 > li.active').forEach(function(li) {
if (li !== a.parentNode)
li.classList.remove('active');
});
if (!ul2)
return;
if (ul2.parentNode.offsetLeft + ul2.offsetWidth <= ul1.offsetLeft + ul1.offsetWidth)
ul2.classList.add('align-left');
ul1.classList.add('active');
a.parentNode.classList.add('active');
a.blur();
ev.preventDefault();
ev.stopPropagation();
},
renderMainMenu: function(tree, url, level) {
var l = (level || 0) + 1,
ul = E('ul', { 'class': 'mainmenu l%d'.format(l) }),
children = ui.menu.getChildren(tree);
if (children.length == 0 || l > 2)
return E([]);
for (var i = 0; i < children.length; i++) {
var isActive = (L.env.dispatchpath[l] == children[i].name),
isReadonly = children[i].readonly,
activeClass = 'mainmenu-item-%s%s'.format(children[i].name, isActive ? ' selected' : '');
ul.appendChild(E('li', { 'class': activeClass }, [
E('a', {
'href': L.url(url, children[i].name),
'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null
}, [ _(children[i].title) ]),
this.renderMainMenu(children[i], url + '/' + children[i].name, l)
]));
}
if (l == 1)
document.querySelector('#mainmenu').appendChild(E('div', [ ul ]));
return ul;
},
renderModeMenu: function(tree, root) {
var menu = document.querySelector('#modemenu'),
children = ui.menu.getChildren(tree);
for (var i = 0; i < children.length; i++) {
var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[+!!root] : i == 0),
isUcentral = (!root && children[i].name == 'ucentral');
if (root || children.length > 1)
menu.appendChild(E('div', { 'class': isActive ? 'active' : null }, [
E('a', { 'href': root ? L.url(root, children[i].name) : L.url(children[i].name) }, [ _(children[i].title) ])
]));
if (isUcentral && isActive)
this.renderModeMenu(children[i], children[i].name);
else if (isActive)
this.renderMainMenu(children[i], children[i].name);
}
if (menu.children.length > 1)
menu.style.display = '';
},
renderTabMenu: function(tree, url, level) {
var container = document.querySelector('#tabmenu'),
l = (level || 0) + 1,
ul = E('ul', { 'class': 'cbi-tabmenu' }),
children = ui.menu.getChildren(tree),
activeNode = null;
if (children.length == 0)
return E([]);
for (var i = 0; i < children.length; i++) {
var isActive = (L.env.dispatchpath[l + 2] == children[i].name),
activeClass = isActive ? ' cbi-tab' : '',
className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass);
ul.appendChild(E('li', { 'class': className }, [
E('a', { 'href': L.url(url, children[i].name) }, [ _(children[i].title) ] )
]));
if (isActive)
activeNode = children[i];
}
container.appendChild(ul);
container.style.display = '';
if (activeNode)
container.appendChild(this.renderTabMenu(activeNode, url + '/' + activeNode.name, l));
return ul;
},
handleSidebarToggle: function(ev) {
var btn = ev.currentTarget,
bar = document.querySelector('#mainmenu');
if (btn.classList.contains('active')) {
btn.classList.remove('active');
bar.classList.remove('active');
}
else {
btn.classList.add('active');
bar.classList.add('active');
}
}
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 251.2 114.2" style="enable-background:new 0 0 251.2 114.2;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FED206;}
.st1{fill:#EB6F53;}
.st2{fill:#3BA9B6;}
.st3{fill:#414141;}
</style>
<g>
<path class="st0" d="M219.6,43.3C219.5,43.3,219.5,43.3,219.6,43.3c-1.3,0-2.2-1-2.2-2.2c0-0.2,0-0.4,0-0.6
c0-11.9-9.7-21.6-21.6-21.6c-0.2,0-0.4,0-0.6,0c-1.2,0-2.2-0.9-2.2-2.1c0-1.2,0.9-2.2,2.1-2.2c0.2,0,0.5,0,0.7,0
c14.3,0,25.9,11.6,25.9,25.9c0,0.2,0,0.5,0,0.7C221.7,42.4,220.7,43.3,219.6,43.3z"/>
<path class="st1" d="M212.1,43.3C212,43.3,212,43.3,212.1,43.3c-1.3-0.1-2.2-1.1-2.2-2.3c0-0.2,0-0.4,0-0.6
c0-7.7-6.3-14.1-14.1-14.1c-0.2,0-0.4,0-0.6,0c-1.2,0.1-2.2-0.9-2.3-2.1c0-1.2,0.9-2.2,2.1-2.3c0.3,0,0.5,0,0.8,0
c10.2,0,18.4,8.3,18.4,18.4c0,0.2,0,0.5,0,0.8C214.2,42.4,213.2,43.3,212.1,43.3z"/>
<path class="st2" d="M204.3,43.3c-0.1,0-0.1,0-0.2,0c-1.2-0.1-2.1-1.1-2-2.3c0-0.2,0-0.4,0-0.5c0-3.5-2.8-6.3-6.3-6.3
c-0.1,0-0.3,0-0.5,0c-1.2,0.1-2.3-0.8-2.3-2c-0.1-1.2,0.8-2.3,2-2.3c0.3,0,0.6,0,0.9,0c5.9,0,10.7,4.8,10.7,10.7c0,0.3,0,0.5,0,0.9
C206.4,42.4,205.4,43.3,204.3,43.3z"/>
<g>
<g>
<g>
<path class="st3" d="M61.9,89.9v-4.7h-1.7v-0.9h4.4v0.9h-1.7v4.7H61.9z"/>
</g>
<g>
<path class="st3" d="M65.6,89.9v-5.6h3.8v0.9h-2.9v1.4h2.8v0.9h-2.8V89h2.9v0.9H65.6z"/>
</g>
<g>
<path class="st3" d="M70.7,89.9v-5.6h1V89h2.5v0.9H70.7z"/>
</g>
<g>
<path class="st3" d="M74.9,89.9v-5.6h3.8v0.9h-2.9v1.4h2.8v0.9h-2.8V89h2.9v0.9H74.9z"/>
</g>
<g>
<path class="st3" d="M79.8,87.1c0-1.7,1.3-2.9,2.9-2.9c1.1,0,1.8,0.6,2.2,1.3l-0.8,0.4c-0.3-0.5-0.8-0.8-1.4-0.8
c-1.1,0-1.9,0.8-1.9,2c0,1.2,0.8,2,1.9,2c0.6,0,1.1-0.4,1.4-0.8l0.8,0.4c-0.4,0.7-1.1,1.3-2.2,1.3C81.1,90,79.8,88.8,79.8,87.1z
"/>
</g>
<g>
<path class="st3" d="M85.5,87.1c0-1.7,1.2-2.9,2.9-2.9c1.7,0,2.9,1.2,2.9,2.9S90,90,88.3,90C86.7,90,85.5,88.8,85.5,87.1z
M90.2,87.1c0-1.2-0.7-2-1.9-2c-1.1,0-1.9,0.9-1.9,2c0,1.1,0.7,2,1.9,2C89.5,89.1,90.2,88.3,90.2,87.1z"/>
</g>
<g>
<path class="st3" d="M96.9,89.9v-4.3l-1.7,4.3h-0.4l-1.7-4.3v4.3h-1v-5.6h1.4l1.5,3.8l1.5-3.8h1.4v5.6H96.9z"/>
</g>
<g>
<path class="st3" d="M103,89.9v-5.6h1v5.6H103z"/>
</g>
<g>
<path class="st3" d="M109.7,89.9l-2.9-4v4h-1v-5.6h1l2.9,3.9v-3.9h1v5.6H109.7z"/>
</g>
<g>
<path class="st3" d="M112.4,89.9v-5.6h3.8v0.9h-2.9v1.4h2.8v0.9h-2.8v2.4H112.4z"/>
</g>
<g>
<path class="st3" d="M120.3,89.9l-1.2-2.1h-1v2.1h-1v-5.6h2.5c1.1,0,1.8,0.7,1.8,1.8c0,1-0.7,1.5-1.3,1.6l1.4,2.2H120.3z
M120.4,86.1c0-0.5-0.4-0.9-1-0.9h-1.4V87h1.4C120,87,120.4,86.6,120.4,86.1z"/>
</g>
<g>
<path class="st3" d="M126.6,89.9l-0.4-1.1h-2.6l-0.4,1.1h-1.1l2.2-5.6h1.2l2.2,5.6H126.6z M124.9,85.3l-1,2.7h2L124.9,85.3z"/>
</g>
<g>
<path class="st3" d="M131.4,89.9v-5.6h2.1c1.1,0,1.7,0.8,1.7,1.6c0,0.9-0.6,1.6-1.7,1.6h-1.6v2.3H131.4z M134.7,86
c0-0.7-0.5-1.2-1.2-1.2h-1.6v2.4h1.6C134.2,87.2,134.7,86.6,134.7,86z"/>
</g>
<g>
<path class="st3" d="M139.4,89.9l-1.6-2.3h-1.2v2.3h-0.5v-5.6h2.1c1,0,1.7,0.6,1.7,1.6c0,1-0.7,1.6-1.6,1.6l1.6,2.3H139.4z
M139.4,86c0-0.7-0.5-1.2-1.2-1.2h-1.6v2.4h1.6C138.9,87.2,139.4,86.7,139.4,86z"/>
</g>
<g>
<path class="st3" d="M141.2,87.1c0-1.6,1.1-2.9,2.7-2.9c1.6,0,2.7,1.3,2.7,2.9c0,1.6-1.1,2.9-2.7,2.9
C142.3,90,141.2,88.8,141.2,87.1z M146.1,87.1c0-1.4-0.9-2.5-2.2-2.5c-1.4,0-2.2,1-2.2,2.5c0,1.4,0.9,2.5,2.2,2.5
C145.2,89.6,146.1,88.5,146.1,87.1z"/>
</g>
<g>
<path class="st3" d="M147,89.3l0.3-0.4c0.3,0.3,0.6,0.6,1.1,0.6c0.8,0,1.2-0.5,1.2-1.3v-4h0.5v4c0,1.2-0.8,1.7-1.7,1.7
C147.9,90,147.4,89.8,147,89.3z"/>
</g>
<g>
<path class="st3" d="M151.8,89.9v-5.6h3.5v0.4h-3.1v2.1h3v0.4h-3v2.2h3.1v0.4H151.8z"/>
</g>
<g>
<path class="st3" d="M156.3,87.1c0-1.7,1.3-2.9,2.8-2.9c0.9,0,1.6,0.4,2,1l-0.4,0.3c-0.4-0.5-1-0.8-1.6-0.8
c-1.3,0-2.3,1-2.3,2.5c0,1.4,1,2.5,2.3,2.5c0.7,0,1.3-0.3,1.6-0.8l0.4,0.3c-0.5,0.6-1.2,1-2,1C157.5,90,156.3,88.8,156.3,87.1z"
/>
</g>
<g>
<path class="st3" d="M163.5,89.9v-5.2h-1.8v-0.4h4.1v0.4H164v5.2H163.5z"/>
</g>
</g>
<g>
<polygon class="st3" points="33.7,86.5 41.2,79 48.6,86.5 49.8,86.5 41.2,77.9 32.6,86.5 "/>
<polygon class="st3" points="48.6,87.8 41.2,95.2 33.7,87.8 32.6,87.8 41.2,96.4 49.8,87.8 "/>
<polygon class="st3" points="40.3,86.5 47.8,79 55.3,86.5 56.4,86.5 47.8,77.9 39.2,86.5 "/>
<polygon class="st3" points="55.3,87.8 47.8,95.2 40.3,87.8 39.2,87.8 47.8,96.4 56.4,87.8 "/>
</g>
</g>
</g>
<g>
<path class="st3" d="M51.2,41.3c2,1.1,3.6,2.6,4.7,4.5c1.1,1.9,1.7,4,1.7,6.4c0,2.3-0.6,4.5-1.7,6.4c-1.1,1.9-2.7,3.4-4.7,4.6
c-2,1.1-4.2,1.7-6.6,1.7c-2.4,0-4.6-0.6-6.6-1.7c-2-1.1-3.6-2.6-4.7-4.6c-1.1-1.9-1.7-4.1-1.7-6.4c0-2.3,0.6-4.5,1.7-6.4
c1.1-1.9,2.7-3.4,4.7-4.5c2-1.1,4.2-1.6,6.6-1.6C47,39.6,49.2,40.2,51.2,41.3z M40.5,44.9c-1.3,0.7-2.3,1.7-3,3
c-0.7,1.3-1.1,2.7-1.1,4.2s0.4,3,1.1,4.2c0.8,1.3,1.8,2.3,3,3c1.3,0.7,2.7,1.1,4.1,1.1c1.5,0,2.8-0.4,4.1-1.1c1.3-0.7,2.3-1.8,3-3
c0.7-1.3,1.1-2.7,1.1-4.2s-0.4-2.9-1.1-4.2c-0.7-1.3-1.7-2.3-3-3c-1.3-0.7-2.6-1.1-4.1-1.1C43.2,43.8,41.8,44.2,40.5,44.9z"/>
<path class="st3" d="M76.9,46.8c1.3,0.8,2.4,1.9,3.1,3.4c0.7,1.4,1.1,3.1,1.1,5c0,1.9-0.4,3.5-1.1,4.9c-0.7,1.4-1.8,2.5-3.1,3.3
c-1.3,0.8-2.9,1.2-4.6,1.2c-1.4,0-2.6-0.3-3.7-0.8c-1.1-0.5-2-1.3-2.7-2.4v9.8h-4.6V45.7H66v3.1c0.7-1.1,1.5-1.8,2.6-2.4
c1.1-0.5,2.3-0.8,3.7-0.8C74,45.6,75.6,46,76.9,46.8z M75.1,59.1c1-1.1,1.5-2.4,1.5-4.1c0-1.7-0.5-3-1.5-4.1
c-1-1.1-2.2-1.6-3.8-1.6c-1.6,0-2.8,0.5-3.8,1.6c-1,1-1.5,2.4-1.5,4.1c0,1.7,0.5,3,1.5,4.1c1,1.1,2.3,1.6,3.8,1.6
C72.8,60.7,74.1,60.2,75.1,59.1z"/>
<path class="st3" d="M99.3,48.1c1.5,1.7,2.3,4.1,2.3,7.2c0,0.6,0,1.1,0,1.4H87.7c0.3,1.3,0.9,2.4,1.9,3.1c0.9,0.8,2.1,1.1,3.5,1.1
c1,0,1.9-0.2,2.7-0.5c0.9-0.4,1.6-0.9,2.3-1.6l2.5,2.6c-0.9,1-2.1,1.8-3.4,2.4c-1.3,0.6-2.8,0.8-4.5,0.8c-1.9,0-3.6-0.4-5.1-1.2
c-1.5-0.8-2.6-1.9-3.4-3.3c-0.8-1.4-1.2-3.1-1.2-5c0-1.9,0.4-3.5,1.2-5c0.8-1.4,1.9-2.6,3.4-3.4c1.4-0.8,3.1-1.2,4.9-1.2
C95.5,45.6,97.8,46.4,99.3,48.1z M97.4,53.6c0-1.4-0.5-2.5-1.4-3.3c-0.9-0.8-2-1.2-3.4-1.2c-1.3,0-2.4,0.4-3.3,1.2
c-0.9,0.8-1.5,1.9-1.7,3.3H97.4z"/>
<path class="st3" d="M121.5,47.5c1.2,1.3,1.9,3.1,1.9,5.3v11.7h-4.6V54.1c0-1.3-0.4-2.3-1.1-3.1c-0.7-0.8-1.8-1.1-3-1.1
c-1.5,0-2.7,0.5-3.6,1.5s-1.3,2.3-1.3,3.8v9.2h-4.5V45.7h4.5v3.5c1.3-2.4,3.5-3.6,6.7-3.7C118.5,45.5,120.2,46.2,121.5,47.5z"/>
<path class="st3" d="M156.5,39.9h4.9l-8.3,24.5h-4.9l-5.6-18.6l-5.7,18.6h-4.8l-8.3-24.5h5l5.8,19.4l5.7-19.4h4.6l5.8,19.5
L156.5,39.9z"/>
<path class="st3" d="M168,38.4c0.5,0.5,0.7,1.2,0.7,2c0,0.8-0.2,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.9,0.8c-0.7,0-1.4-0.3-1.9-0.8
c-0.5-0.5-0.7-1.2-0.7-1.9c0-0.8,0.2-1.4,0.7-2c0.5-0.5,1.1-0.8,1.9-0.8C166.9,37.7,167.6,37.9,168,38.4z M164,45.7h4.5v18.7H164
V45.7z"/>
<path class="st3" d="M174,39.9h16.9l0,4.1h-12.2v6.6h11.1v4.1h-11.1v9.7H174V39.9z"/>
<path class="st3" d="M197.9,38.4c0.5,0.5,0.7,1.2,0.7,2c0,0.8-0.2,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.9,0.8c-0.7,0-1.4-0.3-1.9-0.8
c-0.5-0.5-0.7-1.2-0.7-1.9c0-0.8,0.2-1.4,0.7-2c0.5-0.5,1.1-0.8,1.9-0.8C196.8,37.7,197.4,37.9,197.9,38.4z M193.8,45.7h4.5v18.7
h-4.5V45.7z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="132 132 264 264">
<defs>
<radialGradient id="g" cx="0%" cy="0%" r="60%">
<stop offset=".8" style="stop-opacity:1" />
<stop offset="1" style="stop-opacity:.5" />
</radialGradient>
</defs>
<g>
<path style="fill:url(#g)" d="M 264 132 A 132 132 0 0 0 132 264 A 132 132 0 0 0 264 396 A 132 132 0 0 0 396 264 A 132 132 0 0 0 264 132 z M 264 170 A 94 94 0 0 1 359 264 A 94 94 0 0 1 264 359 A 94 94 0 0 1 170 264 A 94 94 0 0 1 264 170 z " />
</g>
</svg>

After

Width:  |  Height:  |  Size: 582 B

View File

@@ -0,0 +1,13 @@
<%#
Copyright 2021 Jo-Philipp Wich <jo@mein.io>
Licensed to the public under the Apache License 2.0.
-%>
</div>
</div>
</div>
<script type="text/javascript">L.require('menu-ucentral')</script>
</body>
</html>

View File

@@ -0,0 +1,67 @@
<%#
Copyright 2021 Jo-Philipp Wich <jo@mein.io>
Licensed to the public under the Apache License 2.0.
-%>
<%
local sys = require "luci.sys"
local util = require "luci.util"
local http = require "luci.http"
local disp = require "luci.dispatcher"
local ver = require "luci.version"
local boardinfo = util.ubus("system", "board") or { }
local node = disp.context.dispatched
local path = table.concat(disp.context.path, "-")
http.prepare_content("text/html; charset=UTF-8")
-%>
<!DOCTYPE html>
<html lang="<%=luci.i18n.context.lang%>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<link rel="icon" href="<%=media%>/logo.svg" type="image/svg+xml" />
<script type="text/javascript" src="<%=url('admin/translations', luci.i18n.context.lang)%><%# ?v=PKG_VERSION %>"></script>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<title><%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title>
<% if css then %><style title="text/css">
<%= css %>
</style>
<% end -%>
</head>
<body class="lang_<%=luci.i18n.context.lang%>" data-page="<%= pcdata(path) %>">
<p class="skiplink">
<span id="skiplink1"><a href="#navigation"><%:Skip to navigation%></a></span>
<span id="skiplink2"><a href="#content"><%:Skip to content%></a></span>
</p>
<div id="page">
<div id="menubar">
<h2 class="navigation" style="visibility:hidden"><a id="navigation" name="navigation"><%:Navigation%></a></h2>
<img src="<%=media%>/logo.svg" />
<span id="indicators"></span>
</div>
<div id="modemenu" style="display:none"></div>
<div id="maincontainer">
<div id="mainmenu"></div>
<div id="maincontent">
<%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") and path ~= "admin-system-admin-password" then -%>
<div class="alert-message warning">
<h4><%:No password set!%></h4>
<p><%:There is no password set on this router. Please configure a root password to protect the web interface.%></p>
<% if disp.lookup("admin/system/admin") then %>
<div class="right"><a class="btn" href="<%=url("admin/system/admin")%>"><%:Go to password configuration...%></a></div>
<% end %>
</div>
<%- end -%>
<div id="tabmenu" style="display:none"></div>

View File

@@ -0,0 +1,12 @@
#!/bin/sh
if [ "$PKG_UPGRADE" != 1 ]; then
uci get luci.themes.uCentral >/dev/null 2>&1 || \
uci batch <<-EOF
set luci.themes.uCentral=/luci-static/ucentral
set luci.main.mediaurlbase=/luci-static/ucentral
commit luci
EOF
fi
exit 0

294
feeds/tip/luci/luci.mk Normal file
View File

@@ -0,0 +1,294 @@
#
# Copyright (C) 2008-2015 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
LUCI_NAME?=$(notdir ${CURDIR})
LUCI_TYPE?=$(word 2,$(subst -, ,$(LUCI_NAME)))
LUCI_BASENAME?=$(patsubst luci-$(LUCI_TYPE)-%,%,$(LUCI_NAME))
LUCI_LANGUAGES:=$(sort $(filter-out templates,$(notdir $(wildcard ${CURDIR}/po/*))))
LUCI_DEFAULTS:=$(notdir $(wildcard ${CURDIR}/root/etc/uci-defaults/*))
LUCI_PKGARCH?=$(if $(realpath src/Makefile),,all)
# Language code titles
LUCI_LANG.bg=български (Bulgarian)
LUCI_LANG.bn_BD=বাংলা (Bengali)
LUCI_LANG.ca=Català (Catalan)
LUCI_LANG.cs=Čeština (Czech)
LUCI_LANG.de=Deutsch (German)
LUCI_LANG.el=Ελληνικά (Greek)
LUCI_LANG.en=English
LUCI_LANG.es=Español (Spanish)
LUCI_LANG.fr=Français (French)
LUCI_LANG.he=עִבְרִית (Hebrew)
LUCI_LANG.hi=हिंदी (Hindi)
LUCI_LANG.hu=Magyar (Hungarian)
LUCI_LANG.it=Italiano (Italian)
LUCI_LANG.ja=日本語 (Japanese)
LUCI_LANG.ko=한국어 (Korean)
LUCI_LANG.mr=Marāṭhī (Marathi)
LUCI_LANG.ms=Bahasa Melayu (Malay)
LUCI_LANG.nb_NO=Norsk (Norwegian)
LUCI_LANG.pl=Polski (Polish)
LUCI_LANG.pt_BR=Português do Brasil (Brazilian Portuguese)
LUCI_LANG.pt=Português (Portuguese)
LUCI_LANG.ro=Română (Romanian)
LUCI_LANG.ru=Русский (Russian)
LUCI_LANG.sk=Slovenčina (Slovak)
LUCI_LANG.sv=Svenska (Swedish)
LUCI_LANG.tr=Türkçe (Turkish)
LUCI_LANG.uk=Українська (Ukrainian)
LUCI_LANG.vi=Tiếng Việt (Vietnamese)
LUCI_LANG.zh_Hans=简体中文 (Chinese Simplified)
LUCI_LANG.zh_Hant=繁體中文 (Chinese Traditional)
# Submenu titles
LUCI_MENU.col=1. Collections
LUCI_MENU.mod=2. Modules
LUCI_MENU.app=3. Applications
LUCI_MENU.theme=4. Themes
LUCI_MENU.proto=5. Protocols
LUCI_MENU.lib=6. Libraries
# Language aliases
LUCI_LC_ALIAS.bn_BD=bn
LUCI_LC_ALIAS.nb_NO=no
LUCI_LC_ALIAS.pt_BR=pt-br
LUCI_LC_ALIAS.zh_Hans=zh-cn
LUCI_LC_ALIAS.zh_Hant=zh-tw
PKG_NAME?=$(LUCI_NAME)
# 1: everything expect po subdir or only po subdir
define findrev
$(shell \
if git log -1 >/dev/null 2>/dev/null; then \
set -- $$(git log -1 --format="%ct %h" --abbrev=7 -- $(if $(1),. ':(exclude)po',po)); \
if [ -n "$$1" ]; then
secs="$$(($$1 % 86400))"; \
yday="$$(date --utc --date="@$$1" "+%y.%j")"; \
printf 'git-%s.%05d-%s' "$$yday" "$$secs" "$$2"; \
else \
echo "unknown"; \
fi; \
else \
ts=$$(find . -type f $(if $(1),-not) -path './po/*' -printf '%T@\n' 2>/dev/null | sort -rn | head -n1 | cut -d. -f1); \
if [ -n "$$ts" ]; then \
secs="$$(($$ts % 86400))"; \
date="$$(date --utc --date="@$$ts" "+%y%m%d")"; \
printf '%s.%05d' "$$date" "$$secs"; \
else \
echo "unknown"; \
fi; \
fi \
)
endef
PKG_PO_VERSION?=$(if $(DUMP),x,$(strip $(call findrev)))
PKG_SRC_VERSION?=$(if $(DUMP),x,$(strip $(call findrev,1)))
PKG_GITBRANCH?=$(if $(DUMP),x,$(strip $(shell \
variant="LuCI"; \
if git log -1 >/dev/null 2>/dev/null; then \
branch="$$(git branch --remote --verbose --no-abbrev --contains 2>/dev/null | \
sed -rne 's|^[^/]+/([^ ]+) [a-f0-9]{40} .+$$|\1|p' | head -n1)"; \
if [ "$$branch" != "master" ]; then \
variant="LuCI $$branch branch"; \
else \
variant="LuCI Master"; \
fi; \
fi; \
echo "$$variant" \
)))
PKG_RELEASE?=1
PKG_INSTALL:=$(if $(realpath src/Makefile),1)
PKG_BUILD_DEPENDS += lua/host luci-base/host LUCI_CSSTIDY:csstidy/host LUCI_SRCDIET:luasrcdiet/host $(LUCI_BUILD_DEPENDS)
PKG_CONFIG_DEPENDS += CONFIG_LUCI_SRCDIET CONFIG_LUCI_JSMIN CONFIG_LUCI_CSSTIDY
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=$(if $(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.app))
TITLE:=$(if $(LUCI_TITLE),$(LUCI_TITLE),LuCI $(LUCI_NAME) $(LUCI_TYPE))
DEPENDS:=$(LUCI_DEPENDS)
VERSION:=$(if $(PKG_VERSION),$(PKG_VERSION),$(PKG_SRC_VERSION))
$(if $(LUCI_EXTRA_DEPENDS),EXTRA_DEPENDS:=$(LUCI_EXTRA_DEPENDS))
$(if $(LUCI_PKGARCH),PKGARCH:=$(LUCI_PKGARCH))
endef
ifneq ($(LUCI_DESCRIPTION),)
define Package/$(PKG_NAME)/description
$(strip $(LUCI_DESCRIPTION))
endef
endif
# Language selection for luci-base
ifeq ($(PKG_NAME),luci-base)
define Package/luci-base/config
config LUCI_SRCDIET
bool "Minify Lua sources"
default n
config LUCI_JSMIN
bool "Minify JavaScript sources"
default y
config LUCI_CSSTIDY
bool "Minify CSS files"
default y
menu "Translations"$(foreach lang,$(LUCI_LANGUAGES),
config LUCI_LANG_$(lang)
tristate "$(shell echo '$(LUCI_LANG.$(lang))' | sed -e 's/^.* (\(.*\))$$/\1/') ($(lang))")
endmenu
endef
endif
define Build/Prepare
for d in luasrc htdocs root src; do \
if [ -d ./$$$$d ]; then \
mkdir -p $(PKG_BUILD_DIR)/$$$$d; \
$(CP) ./$$$$d/* $(PKG_BUILD_DIR)/$$$$d/; \
fi; \
done
$(call Build/Prepare/Default)
endef
define Build/Configure
endef
ifneq ($(wildcard ${CURDIR}/src/Makefile),)
MAKE_PATH := src/
MAKE_VARS += FPIC="$(FPIC)" LUCI_VERSION="$(PKG_SRC_VERSION)" LUCI_GITBRANCH="$(PKG_GITBRANCH)"
define Build/Compile
$(call Build/Compile/Default,clean compile)
endef
else
define Build/Compile
endef
endif
HTDOCS = /www
LUA_LIBRARYDIR = /usr/lib/lua
LUCI_LIBRARYDIR = $(LUA_LIBRARYDIR)/luci
define SrcDiet
$(FIND) $(1) -type f -name '*.lua' | while read src; do \
if LUA_PATH="$(STAGING_DIR_HOSTPKG)/lib/lua/5.1/?.lua" luasrcdiet --noopt-binequiv -o "$$$$src.o" "$$$$src"; \
then mv "$$$$src.o" "$$$$src"; fi; \
done
endef
define JsMin
$(FIND) $(1) -type f -name '*.js' | while read src; do \
if jsmin < "$$$$src" > "$$$$src.o"; \
then mv "$$$$src.o" "$$$$src"; fi; \
done
endef
define CssTidy
$(FIND) $(1) -type f -name '*.css' | while read src; do \
if csstidy "$$$$src" --template=highest --remove_last_semicolon=true "$$$$src.o"; \
then mv "$$$$src.o" "$$$$src"; fi; \
done
endef
define SubstituteVersion
$(FIND) $(1) -type f -name '*.htm' | while read src; do \
$(SED) 's/<%# *\([^ ]*\)PKG_VERSION *%>/\1$(if $(PKG_VERSION),$(PKG_VERSION),$(PKG_SRC_VERSION))/g' \
-e 's/"\(<%= *\(media\|resource\) *%>[^"]*\.\(js\|css\)\)"/"\1?v=$(if $(PKG_VERSION),$(PKG_VERSION),$(PKG_SRC_VERSION))"/g' \
"$$$$src"; \
done
endef
define Package/$(PKG_NAME)/install
if [ -d $(PKG_BUILD_DIR)/luasrc ]; then \
$(INSTALL_DIR) $(1)$(LUCI_LIBRARYDIR); \
cp -pR $(PKG_BUILD_DIR)/luasrc/* $(1)$(LUCI_LIBRARYDIR)/; \
$(FIND) $(1)$(LUCI_LIBRARYDIR)/ -type f -name '*.luadoc' | $(XARGS) rm; \
$(if $(CONFIG_LUCI_SRCDIET),$(call SrcDiet,$(1)$(LUCI_LIBRARYDIR)/),true); \
$(call SubstituteVersion,$(1)$(LUCI_LIBRARYDIR)/); \
else true; fi
if [ -d $(PKG_BUILD_DIR)/htdocs ]; then \
$(INSTALL_DIR) $(1)$(HTDOCS); \
cp -pR $(PKG_BUILD_DIR)/htdocs/* $(1)$(HTDOCS)/; \
$(if $(CONFIG_LUCI_JSMIN),$(call JsMin,$(1)$(HTDOCS)/),true); \
$(if $(CONFIG_LUCI_CSSTIDY),$(call CssTidy,$(1)$(HTDOCS)/),true); \
else true; fi
if [ -d $(PKG_BUILD_DIR)/root ]; then \
$(INSTALL_DIR) $(1)/; \
cp -pR $(PKG_BUILD_DIR)/root/* $(1)/; \
else true; fi
if [ -d $(PKG_BUILD_DIR)/src ]; then \
$(call Build/Install/Default) \
$(CP) $(PKG_INSTALL_DIR)/* $(1)/; \
else true; fi
endef
ifndef Package/$(PKG_NAME)/postinst
define Package/$(PKG_NAME)/postinst
[ -n "$${IPKG_INSTROOT}" ] || {$(foreach script,$(LUCI_DEFAULTS),
(. /etc/uci-defaults/$(script)) && rm -f /etc/uci-defaults/$(script))
rm -f /tmp/luci-indexcache
rm -rf /tmp/luci-modulecache/
killall -HUP rpcd 2>/dev/null
exit 0
}
endef
endif
LUCI_BUILD_PACKAGES := $(PKG_NAME)
# 1: LuCI language code
# 2: BCP 47 language tag
define LuciTranslation
define Package/luci-i18n-$(LUCI_BASENAME)-$(1)
SECTION:=luci
CATEGORY:=LuCI
TITLE:=$(PKG_NAME) - $(1) translation
HIDDEN:=1
DEFAULT:=LUCI_LANG_$(2)||(ALL&&m)
DEPENDS:=$(PKG_NAME)
VERSION:=$(PKG_PO_VERSION)
PKGARCH:=all
endef
define Package/luci-i18n-$(LUCI_BASENAME)-$(1)/description
Translation for $(PKG_NAME) - $(LUCI_LANG.$(2))
endef
define Package/luci-i18n-$(LUCI_BASENAME)-$(1)/install
$$(INSTALL_DIR) $$(1)/etc/uci-defaults
echo "uci set luci.languages.$(subst -,_,$(1))='$(LUCI_LANG.$(2))'; uci commit luci" \
> $$(1)/etc/uci-defaults/luci-i18n-$(LUCI_BASENAME)-$(1)
$$(INSTALL_DIR) $$(1)$(LUCI_LIBRARYDIR)/i18n
$(foreach po,$(wildcard ${CURDIR}/po/$(2)/*.po), \
po2lmo $(po) \
$$(1)$(LUCI_LIBRARYDIR)/i18n/$(basename $(notdir $(po))).$(1).lmo;)
endef
define Package/luci-i18n-$(LUCI_BASENAME)-$(1)/postinst
[ -n "$$$${IPKG_INSTROOT}" ] || {
(. /etc/uci-defaults/luci-i18n-$(LUCI_BASENAME)-$(1)) && rm -f /etc/uci-defaults/luci-i18n-$(LUCI_BASENAME)-$(1)
exit 0
}
endef
LUCI_BUILD_PACKAGES += luci-i18n-$(LUCI_BASENAME)-$(1)
endef
$(foreach lang,$(LUCI_LANGUAGES),$(eval $(call LuciTranslation,$(firstword $(LUCI_LC_ALIAS.$(lang)) $(lang)),$(lang))))
$(foreach pkg,$(LUCI_BUILD_PACKAGES),$(eval $(call BuildPackage,$(pkg))))

View File

@@ -34,6 +34,15 @@ config_foreach ssid_set wifi-iface
config_load firewall
config_foreach delete_forwarding forwarding
[ -z "$(uci get network.lan)" ] && {
# single port devices wont bring up a lan interface by default
uci set network.lan=interface
uci set network.lan.type=bridge
uci set network.lan.proto=static
uci set network.lan.ipaddr=192.168.1.1
uci set network.lan.netmask=255.255.255.0
}
uci commit
/etc/init.d/uhttpd enable

View File

@@ -0,0 +1,54 @@
#
# Copyright (C) 2008-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qosify
PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0
PKG_BUILD_DEPENDS:=bpf-headers
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
#include $(INCLUDE_DIR)/bpf.mk
define Package/qosify
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
TITLE:=QoS classifier eBPF module
DEPENDS:=+libbpf +libubox +libubus +kmod-sched-cake +tc-full
PKGFLAGS+=nonshared
endef
#BPF_DOC = $(wildcard $(patsubst %,$(BPF_HEADERS_DIR)/scripts/%.py,bpf_doc bpf_helpers_doc))
TARGET_CFLAGS += -I$(BPF_HEADERS_DIR)/user_headers/include
define Build/Compile
# $(call CompileBPF,$(PKG_BUILD_DIR)/qosify-bpf.c)
$(Build/Compile/Default)
endef
define Package/qosify/conffiles
/etc/config/qosify
/etc/qosify-defaults.conf
endef
define Package/qosify/install
$(INSTALL_DIR) $(1)/lib/bpf $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config $(1)/etc/hotplug.d/net
$(INSTALL_DATA) ./files/qosify-bpf.o $(1)/lib/bpf
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qosify $(1)/usr/sbin/
$(INSTALL_BIN) ./files/qosify.init $(1)/etc/init.d/qosify
$(INSTALL_DATA) ./files/qosify-defaults.conf $(1)/etc/qosify-defaults.conf
$(INSTALL_DATA) ./files/qosify.conf $(1)/etc/config/qosify
$(INSTALL_DATA) ./files/qosify.hotplug $(1)/etc/hotplug.d/net/10-qosify
endef
$(eval $(call BuildPackage,qosify))

Binary file not shown.

View File

@@ -0,0 +1,17 @@
# DNS
tcp:53 CS5
tcp:5353 CS5
udp:53 CS5
udp:5353 CS5
# NTP
udp:123 CS6
# SSH
tcp:22 +CS4
# HTTP/QUIC
tcp:80 +CS3
tcp:443 +CS3
udp:80 +CS3
udp:443 +CS3

View File

@@ -0,0 +1,28 @@
config defaults
list defaults /etc/qosify-defaults.conf
option dscp_prio CS5
option dscp_bulk CS0
option dscp_default_udp CS4
option bulk_trigger_timeout 5
option bulk_trigger_pps 100
config interface wan
option name wan
option disabled 1
option bandwidth_up 100mbit
option bandwidth_down 100mbit
# defaults:
option ingress 1
option egress 1
option mode diffserv4
option host_isolate 1
option autorate_ingress 1
option ingress_options ""
option egress_options ""
option options ""
config device wandev
option disabled 1
option name wan
option bandwidth 100mbit

View File

@@ -0,0 +1,2 @@
#!/bin/sh
ubus call qosify check_devices

View File

@@ -0,0 +1,103 @@
#!/bin/sh /etc/rc.common
# Copyright (c) 2014 OpenWrt.org
START=19
USE_PROCD=1
PROG=/usr/sbin/qosify
add_option() {
local type="$1"
local name="$2"
config_get val "$cfg" "$name"
[ -n "$val" ] && json_add_$type "$name" "$val"
}
add_defaults() {
cfg="$1"
json_add_boolean reset 1
config_get files "$cfg" files
json_add_array files
for i in $files; do
json_add_string "" "$i"
done
json_close_array
add_option int timeout
add_option string dscp_prio
add_option string dscp_bulk
add_option string dscp_default_udp
add_option string dscp_default_tcp
add_option int bulk_trigger_timeout
add_option int bulk_trigger_pps
}
add_interface() {
local cfg="$1"
config_get_bool disabled "$cfg" disabled 0
[ "$disabled" -gt 0 ] && return
config_get name "$cfg" name
json_add_object "$name"
config_get bw "$cfg" bandwidth
config_get bw_up "$cfg" bandwidth_up
bw_up="${bw_up:-$bw}"
[ -n "$bw_up" ] && json_add_string bandwidth_up "$bw_up"
config_get bw_down "$cfg" bandwidth_down
bw_down="${bw_down:-$bw}"
[ -n "$bw_down" ] && json_add_string bandwidth_down "$bw_down"
add_option string bandwidth
add_option boolean ingress
add_option boolean egress
add_option string mode
add_option boolean host_isolate
add_option boolean autorate_ingress
add_option string ingress_options
add_option string egress_options
add_option string options
json_close_object
}
reload_service() {
json_init
config_load qosify
config_foreach add_defaults defaults
json_add_object interfaces
config_foreach add_interface interface
json_close_object
json_add_object devices
config_foreach add_interface device
json_close_object
ubus call qosify config "$(json_dump)"
}
service_triggers() {
procd_add_reload_trigger qosify
}
start_service() {
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance
}
service_started() {
ubus -t 10 wait_for qosify
[ $? = 0 ] && reload_service
}

View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.10)
PROJECT(qosify C)
ADD_DEFINITIONS(-Os -Wall -Wno-unknown-warning-option -Wno-array-bounds -Wno-format-truncation -Werror --std=gnu99)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
find_library(bpf NAMES bpf)
ADD_EXECUTABLE(qosify main.c loader.c map.c ubus.c interface.c)
TARGET_LINK_LIBRARIES(qosify ${bpf} ubox ubus)
INSTALL(TARGETS qosify
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
)

View File

@@ -0,0 +1,557 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <unistd.h>
#include <errno.h>
#include <libubox/vlist.h>
#include <libubox/avl-cmp.h>
#include <libubox/uloop.h>
#include "qosify.h"
static void interface_update_cb(struct vlist_tree *tree,
struct vlist_node *node_new,
struct vlist_node *node_old);
static VLIST_TREE(devices, avl_strcmp, interface_update_cb, true, false);
static VLIST_TREE(interfaces, avl_strcmp, interface_update_cb, true, false);
static int socket_fd;
#define APPEND(_buf, _ofs, _format, ...) _ofs += snprintf(_buf + _ofs, sizeof(_buf) - _ofs, _format, ##__VA_ARGS__)
struct qosify_iface_config {
struct blob_attr *data;
bool ingress;
bool egress;
bool nat;
bool host_isolate;
bool autorate_ingress;
const char *bandwidth_up;
const char *bandwidth_down;
const char *mode;
const char *common_opts;
const char *ingress_opts;
const char *egress_opts;
};
struct qosify_iface {
struct vlist_node node;
char ifname[IFNAMSIZ];
bool active;
bool device;
struct blob_attr *config_data;
struct qosify_iface_config config;
};
enum {
IFACE_ATTR_BW_UP,
IFACE_ATTR_BW_DOWN,
IFACE_ATTR_INGRESS,
IFACE_ATTR_EGRESS,
IFACE_ATTR_MODE,
IFACE_ATTR_NAT,
IFACE_ATTR_HOST_ISOLATE,
IFACE_ATTR_AUTORATE_IN,
IFACE_ATTR_INGRESS_OPTS,
IFACE_ATTR_EGRESS_OPTS,
IFACE_ATTR_OPTS,
__IFACE_ATTR_MAX
};
static inline const char *qosify_iface_name(struct qosify_iface *iface)
{
return iface->node.avl.key;
}
static void
iface_config_parse(struct blob_attr *attr, struct blob_attr **tb)
{
static const struct blobmsg_policy policy[__IFACE_ATTR_MAX] = {
[IFACE_ATTR_BW_UP] = { "bandwidth_up", BLOBMSG_TYPE_STRING },
[IFACE_ATTR_BW_DOWN] = { "bandwidth_down", BLOBMSG_TYPE_STRING },
[IFACE_ATTR_INGRESS] = { "ingress", BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_EGRESS] = { "egress", BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_MODE] = { "mode", BLOBMSG_TYPE_STRING },
[IFACE_ATTR_NAT] = { "nat", BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_HOST_ISOLATE] = { "host_isolate", BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_AUTORATE_IN] = { "autorate_ingress", BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_INGRESS_OPTS] = { "ingress_options", BLOBMSG_TYPE_STRING },
[IFACE_ATTR_EGRESS_OPTS] = { "egress_options", BLOBMSG_TYPE_STRING },
[IFACE_ATTR_OPTS] = { "options", BLOBMSG_TYPE_STRING },
};
blobmsg_parse(policy, __IFACE_ATTR_MAX, tb, blobmsg_data(attr), blobmsg_len(attr));
}
static bool
iface_config_equal(struct qosify_iface *if1, struct qosify_iface *if2)
{
struct blob_attr *tb1[__IFACE_ATTR_MAX], *tb2[__IFACE_ATTR_MAX];
int i;
iface_config_parse(if1->config_data, tb1);
iface_config_parse(if2->config_data, tb2);
for (i = 0; i < __IFACE_ATTR_MAX; i++) {
if (!!tb1[i] != !!tb2[i])
return false;
if (!tb1[i])
continue;
if (blob_raw_len(tb1[i]) != blob_raw_len(tb2[i]))
return false;
if (memcmp(tb1[i], tb2[i], blob_raw_len(tb1[i])) != 0)
return false;
}
return true;
}
static const char *check_str(struct blob_attr *attr)
{
const char *str = blobmsg_get_string(attr);
if (strchr(str, '\''))
return NULL;
return str;
}
static void
iface_config_set(struct qosify_iface_config *cfg, struct blob_attr *attr)
{
struct blob_attr *tb[__IFACE_ATTR_MAX];
struct blob_attr *cur;
iface_config_parse(attr, tb);
memset(cfg, 0, sizeof(*cfg));
/* defaults */
cfg->mode = "diffserv4";
cfg->ingress = true;
cfg->egress = true;
cfg->host_isolate = true;
cfg->autorate_ingress = true;
if ((cur = tb[IFACE_ATTR_BW_UP]) != NULL)
cfg->bandwidth_up = check_str(cur);
if ((cur = tb[IFACE_ATTR_BW_DOWN]) != NULL)
cfg->bandwidth_down = check_str(cur);
if ((cur = tb[IFACE_ATTR_MODE]) != NULL)
cfg->mode = check_str(cur);
if ((cur = tb[IFACE_ATTR_OPTS]) != NULL)
cfg->common_opts = check_str(cur);
if ((cur = tb[IFACE_ATTR_EGRESS_OPTS]) != NULL)
cfg->egress_opts = check_str(cur);
if ((cur = tb[IFACE_ATTR_INGRESS_OPTS]) != NULL)
cfg->ingress_opts = check_str(cur);
if ((cur = tb[IFACE_ATTR_INGRESS]) != NULL)
cfg->ingress = blobmsg_get_bool(cur);
if ((cur = tb[IFACE_ATTR_EGRESS]) != NULL)
cfg->egress = blobmsg_get_bool(cur);
if ((cur = tb[IFACE_ATTR_NAT]) != NULL)
cfg->nat = blobmsg_get_bool(cur);
if ((cur = tb[IFACE_ATTR_HOST_ISOLATE]) != NULL)
cfg->host_isolate = blobmsg_get_bool(cur);
if ((cur = tb[IFACE_ATTR_AUTORATE_IN]) != NULL)
cfg->autorate_ingress = blobmsg_get_bool(cur);
}
static const char *
interface_ifb_name(struct qosify_iface *iface)
{
static char ifname[IFNAMSIZ + 1] = "ifb-";
int len = strlen(iface->ifname);
if (len + 4 < IFNAMSIZ) {
snprintf(ifname + 4, IFNAMSIZ - 4, "%s", iface->ifname);
return ifname;
}
ifname[4] = iface->ifname[0];
ifname[5] = iface->ifname[1];
snprintf(ifname + 6, IFNAMSIZ - 6, "%s", iface->ifname + len - (IFNAMSIZ + 6) - 1);
return ifname;
}
static int run_cmd(char *cmd, bool ignore)
{
char *argv[] = { "sh", "-c", cmd, NULL };
bool first = true;
int status = -1;
char buf[512];
int fds[2];
FILE *f;
int pid;
if (pipe(fds))
return -1;
pid = fork();
if (!pid) {
close(fds[0]);
if (fds[1] != STDOUT_FILENO)
dup2(fds[1], STDOUT_FILENO);
if (fds[1] != STDERR_FILENO)
dup2(fds[1], STDERR_FILENO);
if (fds[1] > STDERR_FILENO)
close(fds[1]);
execv("/bin/sh", argv);
exit(1);
}
if (pid < 0)
return -1;
close(fds[1]);
f = fdopen(fds[0], "r");
if (!f) {
close(fds[0]);
goto out;
}
while (fgets(buf, sizeof(buf), f) != NULL) {
if (!strlen(buf))
break;
if (ignore)
continue;
if (first) {
ULOG_WARN("Command: %s\n", cmd);
first = false;
}
ULOG_WARN("%s%s", buf, strchr(buf, '\n') ? "" : "\n");
}
fclose(f);
out:
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
break;
return status;
}
static int
prepare_tc_cmd(char *buf, int len, const char *type, const char *cmd,
const char *dev, const char *extra)
{
return snprintf(buf, len, "tc %s %s dev '%s' %s", type, cmd, dev, extra);
}
static int
cmd_del_qdisc(const char *ifname, const char *type)
{
char buf[64];
prepare_tc_cmd(buf, sizeof(buf), "qdisc", "del", ifname, type);
return run_cmd(buf, true);
}
static int
cmd_add_qdisc(struct qosify_iface *iface, const char *ifname, bool egress, bool eth)
{
struct qosify_iface_config *cfg = &iface->config;
const char *bw = egress ? cfg->bandwidth_up : cfg->bandwidth_down;
const char *dir_opts = egress ? cfg->egress_opts : cfg->ingress_opts;
char buf[512];
int ofs;
cmd_del_qdisc(ifname, "root");
ofs = prepare_tc_cmd(buf, sizeof(buf), "qdisc", "add", ifname, "root handle 1: cake");
if (bw)
APPEND(buf, ofs, " bandwidth %s", bw);
APPEND(buf, ofs, " %s %sgress", cfg->mode, egress ? "e" : "in");
if (cfg->host_isolate)
APPEND(buf, ofs, " %snat dual-%shost",
cfg->nat ? "" : "no",
egress ? "src" : "dst");
else
APPEND(buf, ofs, " flows");
APPEND(buf, ofs, " %s %s",
cfg->common_opts ? cfg->common_opts : "",
dir_opts ? dir_opts : "");
run_cmd(buf, false);
ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", ifname, "parent 1: bpf");
APPEND(buf, ofs, " object-pinned /sys/fs/bpf/qosify_%sgress_%s verbose direct-action",
egress ? "e" : "in",
eth ? "eth" : "ip");
return run_cmd(buf, false);
}
static int
cmd_del_ingress(struct qosify_iface *iface)
{
char buf[256];
cmd_del_qdisc(iface->ifname, "handle ffff: ingress");
snprintf(buf, sizeof(buf), "ip link del '%s'", interface_ifb_name(iface));
return run_cmd(buf, true);
}
static int
cmd_add_ingress(struct qosify_iface *iface, bool eth)
{
const char *ifbdev = interface_ifb_name(iface);
char buf[256];
int ofs;
cmd_del_ingress(iface);
ofs = prepare_tc_cmd(buf, sizeof(buf), "qdisc", "add", iface->ifname, " handle ffff: ingress");
run_cmd(buf, false);
snprintf(buf, sizeof(buf), "ip link add '%s' type ifb", ifbdev);
run_cmd(buf, false);
cmd_add_qdisc(iface, ifbdev, false, eth);
snprintf(buf, sizeof(buf), "ip link set dev '%s' up", ifbdev);
run_cmd(buf, false);
ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " parent ffff:");
APPEND(buf, ofs, " protocol all prio 10 u32 match u32 0 0 "
"flowid 1:1 action mirred egress redirect dev '%s'", ifbdev);
return run_cmd(buf, false);
}
static void
interface_start(struct qosify_iface *iface)
{
struct ifreq ifr = {};
bool eth;
if (!iface->ifname[0] || iface->active)
return;
ULOG_INFO("start interface %s\n", iface->ifname);
strncpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name));
if (ioctl(socket_fd, SIOCGIFHWADDR, &ifr) < 0) {
ULOG_ERR("ioctl(SIOCGIFHWADDR, %s) failed: %s\n", iface->ifname, strerror(errno));
return;
}
eth = ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER;
if (iface->config.egress)
cmd_add_qdisc(iface, iface->ifname, true, eth);
if (iface->config.ingress)
cmd_add_ingress(iface, eth);
iface->active = true;
}
static void
interface_stop(struct qosify_iface *iface)
{
if (!iface->ifname[0] || !iface->active)
return;
ULOG_INFO("stop interface %s\n", iface->ifname);
iface->active = false;
if (iface->config.egress)
cmd_del_qdisc(iface->ifname, "root");
if (iface->config.ingress)
cmd_del_ingress(iface);
}
static void
interface_set_config(struct qosify_iface *iface, struct blob_attr *config)
{
iface->config_data = blob_memdup(config);
iface_config_set(&iface->config, iface->config_data);
interface_start(iface);
}
static void
interface_update_cb(struct vlist_tree *tree,
struct vlist_node *node_new, struct vlist_node *node_old)
{
struct qosify_iface *if_new = NULL, *if_old = NULL;
if (node_new)
if_new = container_of(node_new, struct qosify_iface, node);
if (node_old)
if_old = container_of(node_old, struct qosify_iface, node);
if (if_new && if_old) {
if (!iface_config_equal(if_old, if_new)) {
interface_stop(if_old);
free(if_old->config_data);
interface_set_config(if_old, if_new->config_data);
}
free(if_new);
return;
}
if (if_old) {
interface_stop(if_old);
free(if_old->config_data);
free(if_old);
}
if (if_new)
interface_set_config(if_new, if_new->config_data);
}
static void
interface_create(struct blob_attr *attr, bool device)
{
struct qosify_iface *iface;
const char *name = blobmsg_name(attr);
int name_len = strlen(name);
char *name_buf;
if (strchr(name, '\''))
return;
if (name_len >= IFNAMSIZ)
return;
if (blobmsg_type(attr) != BLOBMSG_TYPE_TABLE)
return;
iface = calloc_a(sizeof(*iface), &name_buf, name_len + 1);
strcpy(name_buf, blobmsg_name(attr));
iface->config_data = attr;
iface->device = device;
vlist_add(device ? &devices : &interfaces, &iface->node, name_buf);
}
void qosify_iface_config_update(struct blob_attr *ifaces, struct blob_attr *devs)
{
struct blob_attr *cur;
int rem;
vlist_update(&devices);
blobmsg_for_each_attr(cur, devs, rem)
interface_create(cur, true);
vlist_flush(&devices);
vlist_update(&interfaces);
blobmsg_for_each_attr(cur, ifaces, rem)
interface_create(cur, false);
vlist_flush(&interfaces);
}
static void
qosify_iface_check_device(struct qosify_iface *iface)
{
const char *name = qosify_iface_name(iface);
int ifindex;
ifindex = if_nametoindex(name);
if (!ifindex) {
interface_stop(iface);
iface->ifname[0] = 0;
} else {
snprintf(iface->ifname, sizeof(iface->ifname), "%s", name);
interface_start(iface);
}
}
static void
qosify_iface_check_interface(struct qosify_iface *iface)
{
const char *name = qosify_iface_name(iface);
char ifname[IFNAMSIZ];
if (qosify_ubus_check_interface(name, ifname, sizeof(ifname)) == 0) {
snprintf(iface->ifname, sizeof(iface->ifname), "%s", ifname);
interface_start(iface);
} else {
interface_stop(iface);
iface->ifname[0] = 0;
}
}
static void qos_iface_check_cb(struct uloop_timeout *t)
{
struct qosify_iface *iface;
vlist_for_each_element(&devices, iface, node)
qosify_iface_check_device(iface);
vlist_for_each_element(&interfaces, iface, node)
qosify_iface_check_interface(iface);
}
void qosify_iface_check(void)
{
static struct uloop_timeout timer = {
.cb = qos_iface_check_cb,
};
uloop_timeout_set(&timer, 10);
}
void qosify_iface_status(struct blob_buf *b)
{
struct qosify_iface *iface;
void *c, *i;
c = blobmsg_open_table(b, "devices");
vlist_for_each_element(&devices, iface, node) {
i = blobmsg_open_table(b, qosify_iface_name(iface));
blobmsg_add_u8(b, "active", iface->active);
blobmsg_close_table(b, i);
}
blobmsg_close_table(b, c);
c = blobmsg_open_table(b, "interfaces");
vlist_for_each_element(&interfaces, iface, node) {
i = blobmsg_open_table(b, qosify_iface_name(iface));
blobmsg_add_u8(b, "active", iface->active);
if (iface->ifname)
blobmsg_add_string(b, "ifname", iface->ifname);
blobmsg_close_table(b, i);
}
blobmsg_close_table(b, c);
}
int qosify_iface_init(void)
{
socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (socket < 0)
return -1;
return 0;
}
void qosify_iface_stop(void)
{
struct qosify_iface *iface;
vlist_for_each_element(&interfaces, iface, node)
interface_stop(iface);
vlist_for_each_element(&devices, iface, node)
interface_stop(iface);
}

View File

@@ -0,0 +1,126 @@
#include <sys/resource.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <glob.h>
#include <unistd.h>
#include "qosify.h"
static int qosify_bpf_pr(enum libbpf_print_level level, const char *format,
va_list args)
{
return vfprintf(stderr, format, args);
}
static void qosify_init_env(void)
{
struct rlimit limit = {
.rlim_cur = RLIM_INFINITY,
.rlim_max = RLIM_INFINITY,
};
setrlimit(RLIMIT_MEMLOCK, &limit);
}
static void qosify_fill_rodata(struct bpf_object *obj, uint32_t flags)
{
struct bpf_map *map = NULL;
while ((map = bpf_map__next(map, obj)) != NULL) {
if (!strstr(bpf_map__name(map), ".rodata"))
continue;
bpf_map__set_initial_value(map, &flags, sizeof(flags));
}
}
static int
qosify_create_program(const char *suffix, uint32_t flags, bool *force_init)
{
DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
.pin_root_path = CLASSIFY_DATA_PATH,
);
struct bpf_program *prog;
struct bpf_object *obj;
struct stat st;
char path[256];
int err;
snprintf(path, sizeof(path), CLASSIFY_PIN_PATH "_" "%s", suffix);
if (!*force_init) {
if (stat(path, &st) == 0)
return 0;
*force_init = true;
}
obj = bpf_object__open_file(CLASSIFY_PROG_PATH, &opts);
err = libbpf_get_error(obj);
if (err) {
perror("bpf_object__open_file");
return -1;
}
prog = bpf_object__find_program_by_title(obj, "classifier");
if (!prog) {
fprintf(stderr, "Can't find classifier prog\n");
return -1;
}
bpf_program__set_type(prog, BPF_PROG_TYPE_SCHED_CLS);
qosify_fill_rodata(obj, flags);
err = bpf_object__load(obj);
if (err) {
perror("bpf_object__load");
return -1;
}
libbpf_set_print(NULL);
unlink(path);
err = bpf_program__pin(prog, path);
if (err) {
fprintf(stderr, "Failed to pin program to %s: %s\n",
path, strerror(-err));
}
bpf_object__close(obj);
return 0;
}
int qosify_loader_init(bool force_init)
{
static const struct {
const char *suffix;
uint32_t flags;
} progs[] = {
{ "egress_eth", 0 },
{ "egress_ip", QOSIFY_IP_ONLY },
{ "ingress_eth", QOSIFY_INGRESS },
{ "ingress_ip", QOSIFY_INGRESS | QOSIFY_IP_ONLY },
};
glob_t g;
int i;
if (force_init &&
glob(CLASSIFY_DATA_PATH "/*", 0, NULL, &g) == 0) {
for (i = 0; i < g.gl_pathc; i++)
unlink(g.gl_pathv[i]);
}
libbpf_set_print(qosify_bpf_pr);
qosify_init_env();
for (i = 0; i < ARRAY_SIZE(progs); i++) {
if (qosify_create_program(progs[i].suffix, progs[i].flags,
&force_init))
return -1;
}
return 0;
}

View File

@@ -0,0 +1,70 @@
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <libubox/uloop.h>
#include "qosify.h"
static int usage(const char *progname)
{
fprintf(stderr, "Usage: %s [options]\n"
"Options:\n"
" -f: force reload of BPF programs\n"
" -l <file> Load defaults from <file>\n"
" -o only load program/maps without running as daemon\n"
"\n", progname);
return 1;
}
int main(int argc, char **argv)
{
const char *load_file = NULL;
bool force_init = false;
bool oneshot = false;
int ch;
while ((ch = getopt(argc, argv, "fl:o")) != -1) {
switch (ch) {
case 'f':
force_init = true;
break;
case 'l':
load_file = optarg;
break;
case 'o':
oneshot = true;
break;
default:
return usage(argv[0]);
}
}
if (qosify_loader_init(force_init))
return 2;
if (qosify_map_init())
return 2;
if (qosify_map_load_file(load_file))
return 2;
if (oneshot)
return 0;
ulog_open(ULOG_SYSLOG, LOG_DAEMON, "qosify");
uloop_init();
if (qosify_ubus_init() ||
qosify_iface_init())
return 2;
uloop_run();
qosify_iface_stop();
uloop_done();
return 0;
}

View File

@@ -0,0 +1,575 @@
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
#include <libubox/uloop.h>
#include "qosify.h"
static int qosify_map_entry_cmp(const void *k1, const void *k2, void *ptr);
static int qosify_map_fds[__CL_MAP_MAX];
static AVL_TREE(map_data, qosify_map_entry_cmp, false, NULL);
static LIST_HEAD(map_files);
static uint32_t next_timeout;
static uint8_t qosify_dscp_default[2] = { 0xff, 0xff };
int qosify_map_timeout = 3600;
struct qosify_config config;
struct qosify_map_file {
struct list_head list;
char filename[];
};
static const struct {
const char *name;
const char *type_name;
} qosify_map_info[] = {
[CL_MAP_TCP_PORTS] = { "tcp_ports", "tcp_port" },
[CL_MAP_UDP_PORTS] = { "udp_ports", "udp_port" },
[CL_MAP_IPV4_ADDR] = { "ipv4_map", "ipv4_addr" },
[CL_MAP_IPV6_ADDR] = { "ipv6_map", "ipv6_addr" },
[CL_MAP_CONFIG] = { "config", "config" },
};
static void qosify_map_timer_cb(struct uloop_timeout *t)
{
qosify_map_gc();
}
static struct uloop_timeout qosify_map_timer = {
.cb = qosify_map_timer_cb,
};
static uint32_t qosify_gettime(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec;
}
static const char *
qosify_map_path(enum qosify_map_id id)
{
static char path[128];
const char *name;
if (id >= ARRAY_SIZE(qosify_map_info))
return NULL;
name = qosify_map_info[id].name;
if (!name)
return NULL;
snprintf(path, sizeof(path), "%s/%s", CLASSIFY_DATA_PATH, name);
return path;
}
static int qosify_map_get_fd(enum qosify_map_id id)
{
const char *path = qosify_map_path(id);
int fd;
if (!path)
return -1;
fd = bpf_obj_get(path);
if (fd < 0)
fprintf(stderr, "Failed to open map %s: %s\n", path, strerror(errno));
return fd;
}
static void qosify_map_clear_list(enum qosify_map_id id)
{
int fd = qosify_map_fds[id];
__u32 key[4] = {};
while (bpf_map_get_next_key(fd, &key, &key) != -1)
bpf_map_delete_elem(fd, &key);
}
static void __qosify_map_set_dscp_default(enum qosify_map_id id, uint8_t val)
{
struct qosify_map_data data = {
.id = id,
};
int fd = qosify_map_fds[id];
int i;
for (i = 0; i < (1 << 16); i++) {
data.addr.port = htons(i);
if (avl_find(&map_data, &data))
continue;
bpf_map_update_elem(fd, &data.addr, &val, BPF_ANY);
}
}
void qosify_map_set_dscp_default(enum qosify_map_id id, uint8_t val)
{
bool udp;
if (id == CL_MAP_TCP_PORTS)
udp = false;
else if (id == CL_MAP_UDP_PORTS)
udp = true;
else
return;
if (qosify_dscp_default[udp] == val)
return;
qosify_dscp_default[udp] = val;
__qosify_map_set_dscp_default(id, val);
}
int qosify_map_init(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(qosify_map_fds); i++) {
qosify_map_fds[i] = qosify_map_get_fd(i);
if (qosify_map_fds[i] < 0)
return -1;
}
qosify_map_clear_list(CL_MAP_IPV4_ADDR);
qosify_map_clear_list(CL_MAP_IPV6_ADDR);
qosify_map_reset_config();
return 0;
}
static char *str_skip(char *str, bool space)
{
while (*str && isspace(*str) == space)
str++;
return str;
}
static int
qosify_map_codepoint(const char *val)
{
static const struct {
const char name[5];
uint8_t val;
} cp[] = {
{ "CS0", 0 },
{ "CS1", 8 },
{ "CS2", 16 },
{ "CS3", 24 },
{ "CS4", 32 },
{ "CS5", 40 },
{ "CS6", 48 },
{ "CS7", 56 },
{ "AF11", 10 },
{ "AF12", 12 },
{ "AF13", 14 },
{ "AF21", 18 },
{ "AF22", 20 },
{ "AF22", 22 },
{ "AF31", 26 },
{ "AF32", 28 },
{ "AF33", 30 },
{ "AF41", 34 },
{ "AF42", 36 },
{ "AF43", 38 },
{ "EF", 46 },
{ "VA", 44 },
};
int i;
for (i = 0; i < ARRAY_SIZE(cp); i++)
if (!strcmp(cp[i].name, val))
return cp[i].val;
return 0xff;
}
static int qosify_map_entry_cmp(const void *k1, const void *k2, void *ptr)
{
const struct qosify_map_data *d1 = k1;
const struct qosify_map_data *d2 = k2;
if (d1->id != d2->id)
return d2->id - d1->id;
return memcmp(&d1->addr, &d2->addr, sizeof(d1->addr));
}
static void __qosify_map_set_entry(struct qosify_map_data *data)
{
int fd = qosify_map_fds[data->id];
struct qosify_map_entry *e;
bool file = data->file;
int32_t delta = 0;
bool add = data->dscp != 0xff;
uint8_t prev_dscp = 0xff;
e = avl_find_element(&map_data, data, e, avl);
if (!e) {
if (!add)
return;
e = calloc(1, sizeof(*e));
e->avl.key = &e->data;
e->data.id = data->id;
memcpy(&e->data.addr, &data->addr, sizeof(e->data.addr));
avl_insert(&map_data, &e->avl);
} else {
prev_dscp = e->data.dscp;
}
if (file)
e->data.file = add;
else
e->data.user = add;
if (add) {
if (file)
e->data.file_dscp = data->dscp;
if (!e->data.user || !file)
e->data.dscp = data->dscp;
} else if (e->data.file && !file) {
e->data.dscp = e->data.file_dscp;
}
if (e->data.dscp != prev_dscp)
bpf_map_update_elem(fd, &data->addr, &e->data.dscp, BPF_ANY);
if (add) {
if (qosify_map_timeout == ~0 || file) {
e->timeout = ~0;
return;
}
e->timeout = qosify_gettime() + qosify_map_timeout;
delta = e->timeout - next_timeout;
if (next_timeout && delta >= 0)
return;
}
uloop_timeout_set(&qosify_map_timer, 1);
}
static int
qosify_map_set_port(struct qosify_map_data *data, const char *str)
{
unsigned long start_port, end_port;
char *err;
int i;
start_port = end_port = strtoul(str, &err, 0);
if (err && *err) {
if (*err == '-')
end_port = strtoul(err + 1, &err, 0);
if (*err)
return -1;
}
if (!start_port || end_port < start_port ||
end_port >= 65535)
return -1;
for (i = start_port; i <= end_port; i++) {
data->addr.port = htons(i);
__qosify_map_set_entry(data);
}
return 0;
}
static int
qosify_map_fill_ip(struct qosify_map_data *data, const char *str)
{
int af;
if (data->id == CL_MAP_IPV6_ADDR)
af = AF_INET6;
else
af = AF_INET;
if (inet_pton(af, str, &data->addr) != 1)
return -1;
return 0;
}
int qosify_map_set_entry(enum qosify_map_id id, bool file, const char *str, uint8_t dscp)
{
struct qosify_map_data data = {
.id = id,
.file = file,
.dscp = dscp,
};
switch (id) {
case CL_MAP_TCP_PORTS:
case CL_MAP_UDP_PORTS:
return qosify_map_set_port(&data, str);
case CL_MAP_IPV4_ADDR:
case CL_MAP_IPV6_ADDR:
if (qosify_map_fill_ip(&data, str))
return -1;
break;
default:
return -1;
}
__qosify_map_set_entry(&data);
return 0;
}
int qosify_map_dscp_value(const char *val)
{
unsigned long dscp;
char *err;
bool fallback = false;
if (*val == '+') {
fallback = true;
val++;
}
dscp = strtoul(val, &err, 0);
if (err && *err)
dscp = qosify_map_codepoint(val);
if (dscp >= 64)
return -1;
return dscp + (fallback << 6);
}
static void
qosify_map_parse_line(char *str)
{
const char *key, *value;
int dscp;
str = str_skip(str, true);
key = str;
str = str_skip(str, false);
if (!*str)
return;
*(str++) = 0;
str = str_skip(str, true);
value = str;
dscp = qosify_map_dscp_value(value);
if (dscp < 0)
return;
if (!strncmp(key, "tcp:", 4))
qosify_map_set_entry(CL_MAP_TCP_PORTS, true, key + 4, dscp);
else if (!strncmp(key, "udp:", 4))
qosify_map_set_entry(CL_MAP_UDP_PORTS, true, key + 4, dscp);
else if (strchr(key, ':'))
qosify_map_set_entry(CL_MAP_IPV6_ADDR, true, key, dscp);
else if (strchr(key, '.'))
qosify_map_set_entry(CL_MAP_IPV4_ADDR, true, key, dscp);
}
static int __qosify_map_load_file(const char *file)
{
char line[1024];
char *cur;
FILE *f;
if (!file)
return 0;
f = fopen(file, "r");
if (!f) {
fprintf(stderr, "Can't open data file %s\n", file);
return -1;
}
while (fgets(line, sizeof(line), f)) {
cur = strchr(line, '#');
if (cur)
*cur = 0;
cur = line + strlen(line);
if (cur == line)
continue;
while (cur > line && isspace(cur[-1]))
cur--;
*cur = 0;
qosify_map_parse_line(line);
}
fclose(f);
return 0;
}
int qosify_map_load_file(const char *file)
{
struct qosify_map_file *f;
if (!file)
return 0;
f = calloc(1, sizeof(*f) + strlen(file) + 1);
strcpy(f->filename, file);
list_add_tail(&f->list, &map_files);
return __qosify_map_load_file(file);
}
static void qosify_map_reset_file_entries(void)
{
struct qosify_map_entry *e;
avl_for_each_element(&map_data, e, avl)
e->data.file = false;
}
void qosify_map_clear_files(void)
{
struct qosify_map_file *f, *tmp;
qosify_map_reset_file_entries();
list_for_each_entry_safe(f, tmp, &map_files, list) {
list_del(&f->list);
free(f);
}
}
void qosify_map_reset_config(void)
{
qosify_map_clear_files();
qosify_map_set_dscp_default(CL_MAP_TCP_PORTS, 0);
qosify_map_set_dscp_default(CL_MAP_UDP_PORTS, 0);
qosify_map_timeout = 3600;
memset(&config, 0, sizeof(config));
config.dscp_prio = 0xff;
config.dscp_bulk = 0xff;
config.dscp_icmp = 0xff;
}
void qosify_map_reload(void)
{
struct qosify_map_file *f;
qosify_map_reset_file_entries();
list_for_each_entry(f, &map_files, list)
__qosify_map_load_file(f->filename);
qosify_map_gc();
}
void qosify_map_gc(void)
{
struct qosify_map_entry *e, *tmp;
int32_t timeout = 0;
uint32_t cur_time = qosify_gettime();
int fd;
next_timeout = 0;
avl_for_each_element_safe(&map_data, e, avl, tmp) {
int32_t cur_timeout;
if (e->data.user && e->timeout != ~0) {
cur_timeout = e->timeout - cur_time;
if (cur_timeout <= 0) {
e->data.user = false;
e->data.dscp = e->data.file_dscp;
} else if (!timeout || cur_timeout < timeout) {
timeout = cur_timeout;
next_timeout = e->timeout;
}
}
if (e->data.file || e->data.user)
continue;
avl_delete(&map_data, &e->avl);
fd = qosify_map_fds[e->data.id];
bpf_map_delete_elem(fd, &e->data.addr);
free(e);
}
if (!timeout)
return;
uloop_timeout_set(&qosify_map_timer, timeout * 1000);
}
void qosify_map_dump(struct blob_buf *b)
{
struct qosify_map_entry *e;
uint32_t cur_time = qosify_gettime();
int buf_len = INET6_ADDRSTRLEN + 1;
char *buf;
void *a;
int af;
a = blobmsg_open_array(b, "entries");
avl_for_each_element(&map_data, e, avl) {
void *c;
if (!e->data.file && !e->data.user)
continue;
c = blobmsg_open_table(b, NULL);
if (e->data.user && e->timeout != ~0) {
int32_t cur_timeout = e->timeout - cur_time;
if (cur_timeout < 0)
cur_timeout = 0;
blobmsg_add_u32(b, "timeout", cur_timeout);
}
blobmsg_add_u8(b, "file", e->data.file);
blobmsg_add_u8(b, "user", e->data.user);
blobmsg_add_string(b, "type", qosify_map_info[e->data.id].type_name);
buf = blobmsg_alloc_string_buffer(b, "value", buf_len);
switch (e->data.id) {
case CL_MAP_TCP_PORTS:
case CL_MAP_UDP_PORTS:
snprintf(buf, buf_len, "%d", ntohs(e->data.addr.port));
break;
case CL_MAP_IPV4_ADDR:
case CL_MAP_IPV6_ADDR:
af = e->data.id == CL_MAP_IPV6_ADDR ? AF_INET6 : AF_INET;
inet_ntop(af, &e->data.addr, buf, buf_len);
break;
default:
*buf = 0;
break;
}
blobmsg_add_string_buffer(b);
blobmsg_close_table(b, c);
}
blobmsg_close_array(b, a);
}
void qosify_map_update_config(void)
{
int fd = qosify_map_fds[CL_MAP_CONFIG];
uint32_t key = 0;
bpf_map_update_elem(fd, &key, &config, BPF_ANY);
}

View File

@@ -0,0 +1,433 @@
#define KBUILD_MODNAME "foo"
#include <uapi/linux/bpf.h>
#include <uapi/linux/if_ether.h>
#include <uapi/linux/if_packet.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/ipv6.h>
#include <uapi/linux/in.h>
#include <uapi/linux/tcp.h>
#include <uapi/linux/udp.h>
#include <uapi/linux/filter.h>
#include <uapi/linux/pkt_cls.h>
#include <linux/ip.h>
#include <net/ipv6.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#include "qosify-bpf.h"
#define INET_ECN_MASK 3
#define DSCP_FALLBACK_FLAG BIT(6)
#define FLOW_CHECK_INTERVAL ((u32)((1000000000ULL) >> 24))
#define FLOW_TIMEOUT ((u32)((30ULL * 1000000000ULL) >> 24))
#define FLOW_BULK_TIMEOUT 5
#define EWMA_SHIFT 12
const volatile static uint32_t module_flags = 0;
struct flow_bucket {
__u32 last_update;
__u32 pkt_len_avg;
__u16 pkt_count;
__u8 dscp;
__u8 bulk_timeout;
};
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(pinning, 1);
__type(key, __u32);
__type(value, struct qosify_config);
__uint(max_entries, 1);
} config SEC(".maps");
typedef struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(pinning, 1);
__type(key, __u32);
__type(value, __u8);
__uint(max_entries, 1 << 16);
} port_array_t;
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(pinning, 1);
__type(key, __u32);
__uint(value_size, sizeof(struct flow_bucket));
__uint(max_entries, QOSIFY_FLOW_BUCKETS);
} flow_map SEC(".maps");
port_array_t tcp_ports SEC(".maps");
port_array_t udp_ports SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(pinning, 1);
__uint(key_size, sizeof(struct in_addr));
__type(value, __u8);
__uint(max_entries, 100000);
__uint(map_flags, BPF_F_NO_PREALLOC);
} ipv4_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(pinning, 1);
__uint(key_size, sizeof(struct in6_addr));
__type(value, __u8);
__uint(max_entries, 100000);
__uint(map_flags, BPF_F_NO_PREALLOC);
} ipv6_map SEC(".maps");
static struct qosify_config *get_config(void)
{
__u32 key = 0;
return bpf_map_lookup_elem(&config, &key);
}
static __always_inline int proto_is_vlan(__u16 h_proto)
{
return !!(h_proto == bpf_htons(ETH_P_8021Q) ||
h_proto == bpf_htons(ETH_P_8021AD));
}
static __always_inline int proto_is_ip(__u16 h_proto)
{
return !!(h_proto == bpf_htons(ETH_P_IP) ||
h_proto == bpf_htons(ETH_P_IPV6));
}
static __always_inline void *skb_ptr(struct __sk_buff *skb, __u32 offset)
{
void *start = (void *)(unsigned long long)skb->data;
return start + offset;
}
static __always_inline void *skb_end_ptr(struct __sk_buff *skb)
{
return (void *)(unsigned long long)skb->data_end;
}
static __always_inline int skb_check(struct __sk_buff *skb, void *ptr)
{
if (ptr > skb_end_ptr(skb))
return -1;
return 0;
}
static __always_inline __u32 cur_time(void)
{
__u32 val = bpf_ktime_get_ns() >> 24;
if (!val)
val = 1;
return val;
}
static __always_inline __u32 ewma(__u32 *avg, __u32 val)
{
if (*avg)
*avg = (*avg * 3) / 4 + (val << EWMA_SHIFT) / 4;
else
*avg = val << EWMA_SHIFT;
return *avg >> EWMA_SHIFT;
}
static __always_inline void
ipv4_change_dsfield(struct iphdr *iph, __u8 mask, __u8 value, bool force)
{
__u32 check = bpf_ntohs(iph->check);
__u8 dsfield;
if ((iph->tos & mask) && !force)
return;
dsfield = (iph->tos & mask) | value;
if (iph->tos == dsfield)
return;
check += iph->tos;
if ((check + 1) >> 16)
check = (check + 1) & 0xffff;
check -= dsfield;
check += check >> 16;
iph->check = bpf_htons(check);
iph->tos = dsfield;
}
static __always_inline void
ipv6_change_dsfield(struct ipv6hdr *ipv6h, __u8 mask, __u8 value, bool force)
{
__u16 *p = (__u16 *)ipv6h;
__u16 val;
if (((*p >> 4) & mask) && !force)
return;
val = (*p & bpf_htons((((__u16)mask << 4) | 0xf00f))) | bpf_htons((__u16)value << 4);
if (val == *p)
return;
*p = val;
}
static __always_inline int
parse_ethernet(struct __sk_buff *skb, __u32 *offset)
{
struct ethhdr *eth;
__u16 h_proto;
int i;
eth = skb_ptr(skb, *offset);
if (skb_check(skb, eth + 1))
return -1;
h_proto = eth->h_proto;
*offset += sizeof(*eth);
#pragma unroll
for (i = 0; i < 2; i++) {
struct vlan_hdr *vlh = skb_ptr(skb, *offset);
if (!proto_is_vlan(h_proto))
break;
if (skb_check(skb, vlh + 1))
return -1;
h_proto = vlh->h_vlan_encapsulated_proto;
*offset += sizeof(*vlh);
}
return h_proto;
}
static void
parse_l4proto(struct qosify_config *config, struct __sk_buff *skb,
__u32 offset, __u8 proto, __u8 *dscp_out)
{
struct udphdr *udp = skb_ptr(skb, offset);
__u32 key;
__u8 *value;
if (skb_check(skb, &udp->len))
return;
if (module_flags & QOSIFY_INGRESS)
key = udp->source;
else
key = udp->dest;
if (proto == IPPROTO_TCP)
value = bpf_map_lookup_elem(&tcp_ports, &key);
else if (proto == IPPROTO_UDP)
value = bpf_map_lookup_elem(&udp_ports, &key);
else {
if ((proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6) &&
config && config->dscp_icmp != 0xff)
*dscp_out = config->dscp_icmp;
return;
}
if (!value)
return;
if ((*value & DSCP_FALLBACK_FLAG) && *dscp_out)
*dscp_out = *value;
}
static void
check_flow(struct qosify_config *config, struct __sk_buff *skb,
uint8_t *dscp)
{
struct flow_bucket flow_data;
struct flow_bucket *flow;
__s32 delta;
__u32 hash;
__u32 time;
if (!config)
return;
time = cur_time();
hash = bpf_get_hash_recalc(skb);
flow = bpf_map_lookup_elem(&flow_map, &hash);
if (!flow) {
memset(&flow_data, 0, sizeof(flow_data));
bpf_map_update_elem(&flow_map, &hash, &flow_data, BPF_ANY);
flow = bpf_map_lookup_elem(&flow_map, &hash);
if (!flow)
return;
}
if (!flow->last_update)
goto reset;
delta = time - flow->last_update;
if ((u32)delta > FLOW_TIMEOUT)
goto reset;
if (delta >= FLOW_CHECK_INTERVAL) {
if (flow->bulk_timeout) {
flow->bulk_timeout--;
if (!flow->bulk_timeout)
flow->dscp = 0xff;
}
goto clear;
}
if (flow->pkt_count < 0xffff)
flow->pkt_count++;
if (flow->pkt_count > config->bulk_trigger_pps) {
flow->dscp = config->dscp_bulk;
flow->bulk_timeout = config->bulk_trigger_timeout;
}
out:
if (config->prio_max_avg_pkt_len &&
flow->dscp != config->dscp_bulk) {
if (ewma(&flow->pkt_len_avg, skb->len) <
config->prio_max_avg_pkt_len)
flow->dscp = config->dscp_prio;
else
flow->dscp = 0xff;
}
if (flow->dscp != 0xff &&
!(*dscp && (flow->dscp & DSCP_FALLBACK_FLAG)))
*dscp = flow->dscp;
return;
reset:
flow->dscp = 0xff;
flow->pkt_len_avg = 0;
clear:
flow->pkt_count = 1;
flow->last_update = time;
goto out;
}
static __always_inline void
parse_ipv4(struct __sk_buff *skb, __u32 *offset)
{
struct qosify_config *config;
const __u32 zero_port = 0;
struct iphdr *iph;
__u8 dscp = 0;
__u8 *value;
int hdr_len;
void *key;
bool force;
config = get_config();
iph = skb_ptr(skb, *offset);
if (skb_check(skb, iph + 1))
return;
hdr_len = iph->ihl * 4;
if (bpf_skb_pull_data(skb, *offset + hdr_len))
return;
iph = skb_ptr(skb, *offset);
*offset += hdr_len;
if (skb_check(skb, (void *)(iph + 1)))
return;
parse_l4proto(config, skb, *offset, iph->protocol, &dscp);
if (module_flags & QOSIFY_INGRESS)
key = &iph->saddr;
else
key = &iph->daddr;
value = bpf_map_lookup_elem(&ipv4_map, key);
/* use udp port 0 entry as fallback for non-tcp/udp */
if (!value)
value = bpf_map_lookup_elem(&udp_ports, &zero_port);
if (value)
dscp = *value;
check_flow(config, skb, &dscp);
force = !(dscp & DSCP_FALLBACK_FLAG);
dscp &= GENMASK(5, 0);
ipv4_change_dsfield(iph, INET_ECN_MASK, dscp << 2, force);
}
static __always_inline void
parse_ipv6(struct __sk_buff *skb, __u32 *offset)
{
struct qosify_config *config;
const __u32 zero_port = 0;
struct ipv6hdr *iph;
__u8 dscp = 0;
__u8 *value;
void *key;
bool force;
config = get_config();
if (bpf_skb_pull_data(skb, *offset + sizeof(*iph)))
return;
iph = skb_ptr(skb, *offset);
*offset += sizeof(*iph);
if (skb_check(skb, (void *)(iph + 1)))
return;
if (module_flags & QOSIFY_INGRESS)
key = &iph->saddr;
else
key = &iph->daddr;
parse_l4proto(config, skb, *offset, iph->nexthdr, &dscp);
value = bpf_map_lookup_elem(&ipv6_map, key);
/* use udp port 0 entry as fallback for non-tcp/udp */
if (!value)
value = bpf_map_lookup_elem(&udp_ports, &zero_port);
if (value)
dscp = *value;
check_flow(config, skb, &dscp);
force = !(dscp & DSCP_FALLBACK_FLAG);
dscp &= GENMASK(5, 0);
ipv6_change_dsfield(iph, INET_ECN_MASK, dscp << 2, force);
}
SEC("classifier")
int classify(struct __sk_buff *skb)
{
__u32 offset = 0;
int type;
if (module_flags & QOSIFY_IP_ONLY)
type = skb->protocol;
else
type = parse_ethernet(skb, &offset);
if (type == bpf_htons(ETH_P_IP))
parse_ipv4(skb, &offset);
else if (type == bpf_htons(ETH_P_IPV6))
parse_ipv6(skb, &offset);
return TC_ACT_OK;
}
char _license[] SEC("license") = "GPL";

View File

@@ -0,0 +1,26 @@
#ifndef __BPF_QOSIFY_H
#define __BPF_QOSIFY_H
#ifndef QOSIFY_FLOW_BUCKET_SHIFT
#define QOSIFY_FLOW_BUCKET_SHIFT 13
#endif
#define QOSIFY_FLOW_BUCKETS (1 << QOSIFY_FLOW_BUCKET_SHIFT)
/* rodata per-instance flags */
#define QOSIFY_INGRESS (1 << 0)
#define QOSIFY_IP_ONLY (1 << 1)
/* global config data */
struct qosify_config {
uint8_t dscp_prio;
uint8_t dscp_bulk;
uint8_t dscp_icmp;
uint8_t bulk_trigger_timeout;
uint16_t bulk_trigger_pps;
uint16_t prio_max_avg_pkt_len;
};
#endif

View File

@@ -0,0 +1,82 @@
#ifndef __QOS_CLASSIFY_H
#define __QOS_CLASSIFY_H
#include <stdbool.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include "qosify-bpf.h"
#include <libubox/utils.h>
#include <libubox/avl.h>
#include <libubox/blobmsg.h>
#include <libubox/ulog.h>
#include <netinet/in.h>
#define CLASSIFY_PROG_PATH "/lib/bpf/qosify-bpf.o"
#define CLASSIFY_PIN_PATH "/sys/fs/bpf/qosify"
#define CLASSIFY_DATA_PATH "/sys/fs/bpf/qosify_data"
enum qosify_map_id {
CL_MAP_TCP_PORTS,
CL_MAP_UDP_PORTS,
CL_MAP_IPV4_ADDR,
CL_MAP_IPV6_ADDR,
CL_MAP_CONFIG,
__CL_MAP_MAX,
};
struct qosify_map_data {
enum qosify_map_id id;
bool file : 1;
bool user : 1;
uint8_t dscp;
uint8_t file_dscp;
union {
uint16_t port;
struct in_addr ip;
struct in6_addr ip6;
} addr;
};
struct qosify_map_entry {
struct avl_node avl;
uint32_t timeout;
struct qosify_map_data data;
};
extern int qosify_map_timeout;
extern struct qosify_config config;
int qosify_loader_init(bool force_init);
int qosify_map_init(void);
int qosify_map_dscp_value(const char *val);
int qosify_map_load_file(const char *file);
int qosify_map_set_entry(enum qosify_map_id id, bool file, const char *str, uint8_t dscp);
void qosify_map_reload(void);
void qosify_map_clear_files(void);
void qosify_map_gc(void);
void qosify_map_dump(struct blob_buf *b);
void qosify_map_set_dscp_default(enum qosify_map_id id, uint8_t val);
void qosify_map_reset_config(void);
void qosify_map_update_config(void);
int qosify_iface_init(void);
void qosify_iface_config_update(struct blob_attr *ifaces, struct blob_attr *devs);
void qosify_iface_check(void);
void qosify_iface_status(struct blob_buf *b);
void qosify_iface_stop(void);
int qosify_ubus_init(void);
int qosify_ubus_check_interface(const char *name, char *ifname, int ifname_len);
#endif

View File

@@ -0,0 +1,364 @@
#include <libubus.h>
#include "qosify.h"
static struct blob_buf b;
static int
qosify_ubus_add_array(struct blob_attr *attr, uint8_t val, enum qosify_map_id id)
{
struct blob_attr *cur;
int rem;
if (blobmsg_check_array(attr, BLOBMSG_TYPE_STRING) < 0)
return UBUS_STATUS_INVALID_ARGUMENT;
blobmsg_for_each_attr(cur, attr, rem)
qosify_map_set_entry(id, false, blobmsg_get_string(cur), val);
return 0;
}
static int
qosify_ubus_set_files(struct blob_attr *attr)
{
struct blob_attr *cur;
int rem;
if (blobmsg_check_array(attr, BLOBMSG_TYPE_STRING) < 0)
return UBUS_STATUS_INVALID_ARGUMENT;
qosify_map_clear_files();
blobmsg_for_each_attr(cur, attr, rem)
qosify_map_load_file(blobmsg_get_string(cur));
qosify_map_gc();
return 0;
}
enum {
CL_ADD_DSCP,
CL_ADD_TIMEOUT,
CL_ADD_IPV4,
CL_ADD_IPV6,
CL_ADD_TCP_PORT,
CL_ADD_UDP_PORT,
__CL_ADD_MAX
};
static const struct blobmsg_policy qosify_add_policy[__CL_ADD_MAX] = {
[CL_ADD_DSCP] = { "dscp", BLOBMSG_TYPE_STRING },
[CL_ADD_TIMEOUT] = { "timeout", BLOBMSG_TYPE_INT32 },
[CL_ADD_IPV4] = { "ipv4", BLOBMSG_TYPE_ARRAY },
[CL_ADD_IPV6] = { "ipv6", BLOBMSG_TYPE_ARRAY },
[CL_ADD_TCP_PORT] = { "tcp_port", BLOBMSG_TYPE_ARRAY },
[CL_ADD_UDP_PORT] = { "udp_port", BLOBMSG_TYPE_ARRAY },
};
static int
qosify_ubus_reload(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
qosify_map_reload();
return 0;
}
static int
qosify_ubus_add(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int prev_timemout = qosify_map_timeout;
struct blob_attr *tb[__CL_ADD_MAX];
struct blob_attr *cur;
int dscp = -1;
int ret;
blobmsg_parse(qosify_add_policy, __CL_ADD_MAX, tb,
blobmsg_data(msg), blobmsg_len(msg));
if (!strcmp(method, "add")) {
if ((cur = tb[CL_ADD_DSCP]) != NULL)
dscp = qosify_map_dscp_value(blobmsg_get_string(cur));
else
return UBUS_STATUS_INVALID_ARGUMENT;
if (dscp < 0)
return UBUS_STATUS_INVALID_ARGUMENT;
if ((cur = tb[CL_ADD_TIMEOUT]) != NULL)
qosify_map_timeout = blobmsg_get_u32(cur);
} else {
dscp = 0xff;
}
if ((cur = tb[CL_ADD_IPV4]) != NULL &&
(ret = qosify_ubus_add_array(cur, dscp, CL_MAP_IPV4_ADDR) != 0))
return ret;
if ((cur = tb[CL_ADD_IPV6]) != NULL &&
(ret = qosify_ubus_add_array(cur, dscp, CL_MAP_IPV6_ADDR) != 0))
return ret;
if ((cur = tb[CL_ADD_TCP_PORT]) != NULL &&
(ret = qosify_ubus_add_array(cur, dscp, CL_MAP_TCP_PORTS) != 0))
return ret;
if ((cur = tb[CL_ADD_UDP_PORT]) != NULL &&
(ret = qosify_ubus_add_array(cur, dscp, CL_MAP_UDP_PORTS) != 0))
return ret;
qosify_map_timeout = prev_timemout;
return 0;
}
enum {
CL_CONFIG_RESET,
CL_CONFIG_FILES,
CL_CONFIG_TIMEOUT,
CL_CONFIG_DSCP_UDP,
CL_CONFIG_DSCP_TCP,
CL_CONFIG_DSCP_PRIO,
CL_CONFIG_DSCP_BULK,
CL_CONFIG_DSCP_ICMP,
CL_CONFIG_BULK_TIMEOUT,
CL_CONFIG_BULK_PPS,
CL_CONFIG_PRIO_PKT_LEN,
CL_CONFIG_INTERFACES,
CL_CONFIG_DEVICES,
__CL_CONFIG_MAX
};
static const struct blobmsg_policy qosify_config_policy[__CL_CONFIG_MAX] = {
[CL_CONFIG_RESET] = { "reset", BLOBMSG_TYPE_BOOL },
[CL_CONFIG_FILES] = { "files", BLOBMSG_TYPE_ARRAY },
[CL_CONFIG_TIMEOUT] = { "timeout", BLOBMSG_TYPE_INT32 },
[CL_CONFIG_DSCP_UDP] = { "dscp_default_tcp", BLOBMSG_TYPE_STRING },
[CL_CONFIG_DSCP_TCP] = { "dscp_default_udp", BLOBMSG_TYPE_STRING },
[CL_CONFIG_DSCP_PRIO] = { "dscp_prio", BLOBMSG_TYPE_STRING },
[CL_CONFIG_DSCP_BULK] = { "dscp_bulk", BLOBMSG_TYPE_STRING },
[CL_CONFIG_DSCP_ICMP] = { "dscp_icmp", BLOBMSG_TYPE_STRING },
[CL_CONFIG_BULK_TIMEOUT] = { "bulk_trigger_timeout", BLOBMSG_TYPE_INT32 },
[CL_CONFIG_BULK_PPS] = { "bulk_trigger_pps", BLOBMSG_TYPE_INT32 },
[CL_CONFIG_PRIO_PKT_LEN] = { "prio_max_avg_pkt_len", BLOBMSG_TYPE_INT32 },
[CL_CONFIG_INTERFACES] = { "interfaces", BLOBMSG_TYPE_TABLE },
[CL_CONFIG_DEVICES] = { "devices", BLOBMSG_TYPE_TABLE },
};
static int __set_dscp(uint8_t *dest, struct blob_attr *attr, bool reset)
{
int dscp;
if (reset)
*dest = 0xff;
if (!attr)
return 0;
dscp = qosify_map_dscp_value(blobmsg_get_string(attr));
if (dscp < 0)
return -1;
*dest = dscp;
return 0;
}
static int
qosify_ubus_config(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
struct blob_attr *tb[__CL_CONFIG_MAX];
struct blob_attr *cur;
uint8_t dscp;
bool reset = false;
int ret;
blobmsg_parse(qosify_config_policy, __CL_CONFIG_MAX, tb,
blobmsg_data(msg), blobmsg_len(msg));
if ((cur = tb[CL_CONFIG_RESET]) != NULL)
reset = blobmsg_get_bool(cur);
if (reset)
qosify_map_reset_config();
if ((cur = tb[CL_CONFIG_TIMEOUT]) != NULL)
qosify_map_timeout = blobmsg_get_u32(cur);
if ((cur = tb[CL_CONFIG_FILES]) != NULL &&
(ret = qosify_ubus_set_files(cur) != 0))
return ret;
__set_dscp(&dscp, tb[CL_CONFIG_DSCP_UDP], true);
if (dscp != 0xff)
qosify_map_set_dscp_default(CL_MAP_UDP_PORTS, dscp);
__set_dscp(&dscp, tb[CL_CONFIG_DSCP_TCP], true);
if (dscp != 0xff)
qosify_map_set_dscp_default(CL_MAP_TCP_PORTS, dscp);
__set_dscp(&config.dscp_prio, tb[CL_CONFIG_DSCP_PRIO], reset);
__set_dscp(&config.dscp_bulk, tb[CL_CONFIG_DSCP_BULK], reset);
__set_dscp(&config.dscp_icmp, tb[CL_CONFIG_DSCP_ICMP], reset);
if ((cur = tb[CL_CONFIG_BULK_TIMEOUT]) != NULL)
config.bulk_trigger_timeout = blobmsg_get_u32(cur);
if ((cur = tb[CL_CONFIG_BULK_PPS]) != NULL)
config.bulk_trigger_pps = blobmsg_get_u32(cur);
if ((cur = tb[CL_CONFIG_PRIO_PKT_LEN]) != NULL)
config.prio_max_avg_pkt_len = blobmsg_get_u32(cur);
qosify_map_update_config();
qosify_iface_config_update(tb[CL_CONFIG_INTERFACES], tb[CL_CONFIG_DEVICES]);
qosify_iface_check();
return 0;
}
static int
qosify_ubus_dump(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
blob_buf_init(&b, 0);
qosify_map_dump(&b);
ubus_send_reply(ctx, req, b.head);
blob_buf_free(&b);
return 0;
}
static int
qosify_ubus_status(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
blob_buf_init(&b, 0);
qosify_iface_status(&b);
ubus_send_reply(ctx, req, b.head);
blob_buf_free(&b);
return 0;
}
enum {
CL_DEV_EVENT_NAME,
CL_DEV_EVENT_ADD,
__CL_DEV_EVENT_MAX,
};
static int
qosify_ubus_check_devices(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
qosify_iface_check();
return 0;
}
static const struct ubus_method qosify_methods[] = {
UBUS_METHOD_NOARG("reload", qosify_ubus_reload),
UBUS_METHOD("add", qosify_ubus_add, qosify_add_policy),
UBUS_METHOD_MASK("remove", qosify_ubus_add, qosify_add_policy,
((1 << __CL_ADD_MAX) - 1) & ~(1 << CL_ADD_DSCP)),
UBUS_METHOD("config", qosify_ubus_config, qosify_config_policy),
UBUS_METHOD_NOARG("dump", qosify_ubus_dump),
UBUS_METHOD_NOARG("status", qosify_ubus_status),
UBUS_METHOD_NOARG("check_devices", qosify_ubus_check_devices),
};
static struct ubus_object_type qosify_object_type =
UBUS_OBJECT_TYPE("qosify", qosify_methods);
static struct ubus_object qosify_object = {
.name = "qosify",
.type = &qosify_object_type,
.methods = qosify_methods,
.n_methods = ARRAY_SIZE(qosify_methods),
};
static void
ubus_connect_handler(struct ubus_context *ctx)
{
ubus_add_object(ctx, &qosify_object);
}
static struct ubus_auto_conn conn;
int qosify_ubus_init(void)
{
conn.cb = ubus_connect_handler;
ubus_auto_connect(&conn);
return 0;
}
struct iface_req {
char *name;
int len;
};
static void
netifd_if_cb(struct ubus_request *req, int type, struct blob_attr *msg)
{
struct iface_req *ifr = req->priv;
enum {
IFS_ATTR_UP,
IFS_ATTR_DEV,
__IFS_ATTR_MAX
};
static const struct blobmsg_policy policy[__IFS_ATTR_MAX] = {
[IFS_ATTR_UP] = { "up", BLOBMSG_TYPE_BOOL },
[IFS_ATTR_DEV] = { "l3_device", BLOBMSG_TYPE_STRING },
};
struct blob_attr *tb[__IFS_ATTR_MAX];
blobmsg_parse(policy, __IFS_ATTR_MAX, tb, blobmsg_data(msg), blobmsg_len(msg));
if (!tb[IFS_ATTR_UP] || !tb[IFS_ATTR_DEV])
return;
if (!blobmsg_get_bool(tb[IFS_ATTR_UP]))
return;
snprintf(ifr->name, ifr->len, "%s", blobmsg_get_string(tb[IFS_ATTR_DEV]));
}
int qosify_ubus_check_interface(const char *name, char *ifname, int ifname_len)
{
struct iface_req req = { ifname, ifname_len };
char *obj_name = "network.interface.";
uint32_t id;
#define PREFIX "network.interface."
obj_name = alloca(sizeof(PREFIX) + strlen(name) + 1);
sprintf(obj_name, PREFIX "%s", name);
#undef PREFIX
ifname[0] = 0;
if (ubus_lookup_id(&conn.ctx, obj_name, &id))
return -1;
ubus_invoke(&conn.ctx, id, "status", b.head, netifd_if_cb, &req, 1000);
if (!ifname[0])
return -1;
return 0;
}

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/blogic/ucentral-client.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-02-15
PKG_SOURCE_VERSION:=06704453bec36baf96919021507627b1f1d4e6e4
PKG_SOURCE_VERSION:=0179c0f98039b0fe6492b6f98e321c7e80dff42d
PKG_LICENSE:=BSD-3-Clause
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
@@ -18,7 +18,7 @@ define Package/ucentral-client
SECTION:=ucentral
CATEGORY:=uCentral
TITLE:=OpenWrt uCentral websocket client
DEPENDS:=+ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci +ucode-mod-math \
DEPENDS:=+ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci +ucode-mod-math +ucode-mod-resolv \
+libubox +libwebsockets-openssl +libblobmsg-json +libubus
endef

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/blogic/ucentral-event.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-04-13
PKG_SOURCE_VERSION:=863be47d264ea3fefccadfcfa53c1af53f54dd3b
PKG_SOURCE_VERSION:=7b0d136e8556bb099d7032823139d275448714cb
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/blogic/ucentral-schema.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-02-15
PKG_SOURCE_VERSION:=224042e57012b72231c5d402816a83fab5bbf54f
PKG_SOURCE_VERSION:=1bdc8de73f66d5b846cc07c2697959c0cfda6aee
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -1,5 +1,14 @@
{
"uuid": 2,
"radios": [
{
"band": "2G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80,
"channel": 32
}
],
"interfaces": [
{
"name": "WAN",
@@ -34,7 +43,21 @@
"lease-count": 100,
"lease-time": "6h"
}
}
},
"ssids": [
{
"name": "Metric",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
}
}
]
}
],
"metrics": {

View File

@@ -0,0 +1,136 @@
{
"uuid": 2,
"globals": {
"wireless-multimedia": {
"UP0": [ "DF"],
"UP1": [ "CS1" ],
"UP2": [ "AF11", "AF12", "AF13" ],
"UP3": [ "CS2", "AF21", "AF22", "AF23" ],
"UP4": [ "CS3", "AF31", "AF32", "AF33" ],
"UP5": [ "CS5", "AF41", "AF42", "AF43" ],
"UP6": [ "CS4", "EF" ],
"UP7": [ "CS6" ]
}
},
"radios": [
{
"band": "2G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80,
"channel": 32
}
],
"interfaces": [
{
"name": "WAN",
"role": "upstream",
"services": [ "lldp" ],
"ethernet": [
{
"select-ports": [
"WAN*"
]
}
],
"ipv4": {
"addressing": "dynamic"
},
"ssids": [
{
"name": "OpenWifi",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
}
}
]
},
{
"name": "LAN",
"role": "downstream",
"services": [ "ssh", "lldp" ],
"ethernet": [
{
"select-ports": [
"LAN*"
]
}
],
"ipv4": {
"addressing": "static",
"subnet": "192.168.1.1/24",
"dhcp": {
"lease-first": 10,
"lease-count": 100,
"lease-time": "6h"
}
},
"ssids": [
{
"name": "OpenWifi",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
}
}
]
}
],
"metrics": {
"statistics": {
"interval": 120,
"types": [ "ssids", "lldp", "clients" ]
},
"health": {
"interval": 120
}
},
"services": {
"lldp": {
"describe": "uCentral",
"location": "universe"
},
"ssh": {
"port": 22
},
"quality-of-service": {
"select-ports": [ "WAN" ],
"bandwidth_up": 1000,
"bandwidth_down": 1000,
"classifier": [
{
"dscp": "CS0",
"ports": [
{ "protocol": "any", "port": 53 },
{ "protocol": "tcp", "port": 80 }
],
"dns": [
"telecominfraproject.com"
]
}, {
"dscp": "CS1",
"ports": [
{ "protocol": "any", "port": 53, "range-end": 80 },
{ "protocol": "udp", "port": 80, "reclassify": true }
],
"dns": [
"telecominfraproject.com"
]
}
]
}
}
}

View File

@@ -0,0 +1,94 @@
{
"uuid": 2,
"ethernet": [
{
"select-ports": [
"WAN1"
],
"speed": 100,
"duplex": "half"
},
{
"select-ports": [
"WAN2"
],
"speed": 1000,
"duplex": "full"
},
{
"select-ports": [
"WAN3"
],
"speed": 100,
"duplex": "half"
}
],
"interfaces": [
{
"name": "WAN100",
"role": "upstream",
"services": [ "lldp", "ssh" ],
"ethernet": [
{
"select-ports": [
"WAN1", "WAN2", "WAN3"
],
"vlan-tag": "un-tagged"
}, {
"select-ports": [
"WAN7", "WAN8"
]
}
],
"vlan": {
"id": 100
},
"ipv4": {
"addressing": "dynamic"
}
},
{
"name": "WAN200",
"role": "upstream",
"services": [ "lldp", "ssh" ],
"ethernet": [
{
"select-ports": [
"WAN4", "WAN5", "WAN6"
],
"vlan-tag": "un-tagged"
}, {
"select-ports": [
"WAN7", "WAN8"
]
}
],
"vlan": {
"id": 101
},
"ipv4": {
"addressing": "dynamic"
}
}
],
"metrics": {
"statistics": {
"interval": 120,
"types": [ "ssids", "lldp", "clients" ]
},
"health": {
"interval": 120
}
},
"services": {
"lldp": {
"describe": "uCentral",
"location": "universe"
},
"ssh": {
"port": 22
}
}
}

View File

@@ -0,0 +1,5 @@
#!/bin/sh
uci delete qosify.wan
uci delete qosify.wandev
uci set qosify.@defaults[-1].defaults=/tmp/qosify.conf

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/blogic/ucentral-wifi.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-04-13
PKG_SOURCE_VERSION:=cadac1243bb2577f1f228fa18bba71926201786c
PKG_SOURCE_VERSION:=b6dd24f79b14346e767fdda7206ad8c9d851ab35
#PKG_MIRROR_HASH:=a8000b3cf43ce9ebfa7305661475fec98ec1dba2dc7b062028c2e17d7c2ec50b
PKG_MAINTAINER:=John Crispin <john@phrozen.org>

View File

@@ -13,7 +13,7 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/jow-/ucode.git
PKG_SOURCE_DATE:=2021-07-30
PKG_SOURCE_VERSION:=5b908bdf64a586d27d5bdd1df8c72a7cd63b386a
PKG_SOURCE_VERSION:=0f022aae0c6008fe6f2219871d32dca8b9105066
PKG_MIRROR_HASH:=
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_LICENSE:=ISC
@@ -65,6 +65,17 @@ define Package/ucode-mod-fs/description
endef
define Package/ucode-mod-resolv
$(Package/ucode/default)
TITLE+= (resolv module)
DEPENDS:=ucode
endef
define Package/ucode-mod-resolv/description
The resolv plugin module allows making DNS resolves.
endef
define Package/ucode-mod-math
$(Package/ucode/default)
TITLE+= (math module)
@@ -121,6 +132,11 @@ define Package/ucode-mod-fs/install
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/ucode/fs.so $(1)/usr/lib/ucode/
endef
define Package/ucode-mod-resolv/install
$(INSTALL_DIR) $(1)/usr/lib/ucode
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/ucode/resolv.so $(1)/usr/lib/ucode/
endef
define Package/ucode-mod-math/install
$(INSTALL_DIR) $(1)/usr/lib/ucode
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/ucode/math.so $(1)/usr/lib/ucode/
@@ -140,6 +156,7 @@ endef
$(eval $(call BuildPackage,ucode))
$(eval $(call BuildPackage,libucode))
$(eval $(call BuildPackage,ucode-mod-fs))
$(eval $(call BuildPackage,ucode-mod-resolv))
$(eval $(call BuildPackage,ucode-mod-math))
$(eval $(call BuildPackage,ucode-mod-ubus))
$(eval $(call BuildPackage,ucode-mod-uci))

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/blogic/udevmand.git
PKG_SOURCE_DATE:=20200623
PKG_SOURCE_VERSION:=5115b6ff4187e344767dae21daf1cbc210bb03fb
PKG_SOURCE_VERSION:=b5a68ca17b67659ac7a1d233ebea3507a486e65a
CMAKE_INSTALL:=1
PKG_LICENSE:=LGPL-2.1

View File

@@ -27,9 +27,11 @@ ALLWIFIBOARDS:= \
cig-wf188 \
cig-wf188n \
cig-wf194c \
cig-wf194c4 \
edgecore-eap101 \
sercomm-wallaby \
edgecore-eap102 \
wallys-dr6018 \
tplink-ex227 \
tplink-ex447
@@ -129,7 +131,9 @@ endef
$(eval $(call generate-ath11k-wifi-package,cig-wf188,Cigtech WF188))
$(eval $(call generate-ath11k-wifi-package,cig-wf188n,Cigtech WF188n))
$(eval $(call generate-ath11k-wifi-package,cig-wf194c,Cigtech WF194c))
$(eval $(call generate-ath11k-wifi-package,cig-wf194c4,Cigtech WF194c4))
$(eval $(call generate-ath11k-wifi-package,sercomm-wallaby,Sercomm Kiwi))
$(eval $(call generate-ath11k-wifi-package,wallys-dr6018,Wallys DR6018))
$(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,tplink-ex227,TP-Link EX227))

View File

@@ -48,14 +48,17 @@ hostapd_append_wpa_key_mgmt() {
;;
eap192)
append wpa_key_mgmt "WPA-EAP-SUITE-B-192"
append wpa_key_mgmt "WPA-EAP-SHA256"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
[ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-EAP-SHA256"
;;
eap-eap192)
append wpa_key_mgmt "WPA-EAP-SUITE-B-192"
eap-eap256)
append wpa_key_mgmt "WPA-EAP"
append wpa_key_mgmt "WPA-EAP-SHA256"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
;;
eap256)
append wpa_key_mgmt "WPA-EAP-SHA256"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
[ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-EAP-SHA256"
;;
sae)
append wpa_key_mgmt "SAE"
@@ -603,11 +606,11 @@ hostapd_set_bss_options() {
}
case "$auth_type" in
sae|owe|eap192|eap-eap192)
sae|owe|eap192|eap256)
set_default ieee80211w 2
set_default sae_require_mfp 1
;;
psk-sae)
psk-sae|eap-eap256)
set_default ieee80211w 1
set_default sae_require_mfp 1
;;
@@ -650,7 +653,7 @@ hostapd_set_bss_options() {
vlan_possible=1
wps_possible=1
;;
eap|eap192|eap-eap192)
eap|eap192|eap-eap256|eap256)
json_get_vars \
auth_server auth_secret auth_port \
dae_client dae_secret dae_port \
@@ -754,7 +757,7 @@ hostapd_set_bss_options() {
}
append bss_conf "ssid=$ssid" "$N"
[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge${N}wds_bridge=" "$N"
[ -n "$network_ifname" ] && append bss_conf "snoop_iface=$network_ifname" "$N"
[ -n "$iapp_interface" ] && {
local ifname
@@ -886,7 +889,16 @@ hostapd_set_bss_options() {
json_get_vars ieee80211w_mgmt_cipher ieee80211w_max_timeout ieee80211w_retry_timeout
append bss_conf "ieee80211w=$ieee80211w" "$N"
[ "$ieee80211w" -gt "0" ] && {
append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N"
case "$auth_type" in
eap192)
append bss_conf "group_mgmt_cipher=BIP-GMAC-256" "$N"
append bss_conf "group_cipher=GCMP-256" "$N"
;;
*)
append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N"
;;
esac
[ -n "$ieee80211w_max_timeout" ] && \
append bss_conf "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N"
[ -n "$ieee80211w_retry_timeout" ] && \
@@ -974,7 +986,6 @@ hostapd_set_bss_options() {
[ -n "$iw_network_auth_type" ] && \
append bss_conf "network_auth_type=$iw_network_auth_type" "$N"
[ -n "$iw_gas_address3" ] && append bss_conf "gas_address3=$iw_gas_address3" "$N"
[ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N"
json_for_each_item append_iw_roaming_consortium iw_roaming_consortium
json_for_each_item append_iw_anqp_elem iw_anqp_elem
@@ -992,6 +1003,7 @@ hostapd_set_bss_options() {
[ -n "$iw_anqp_3gpp_cell_net_conf" ] && \
append bss_conf "anqp_3gpp_cell_net=$iw_anqp_3gpp_cell_net_conf" "$N"
fi
[ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N"
local hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \
@@ -1200,10 +1212,10 @@ wpa_supplicant_add_network() {
default_disabled
case "$auth_type" in
sae|owe|eap192|eap-eap192)
sae|owe|eap-eap256)
set_default ieee80211w 2
;;
psk-sae)
psk-sae|eap192|eap256)
set_default ieee80211w 1
;;
esac
@@ -1281,7 +1293,7 @@ wpa_supplicant_add_network() {
fi
append network_data "$passphrase" "$N$T"
;;
eap|eap192|eap-eap192)
eap|eap192|eap-eap256|eap256)
hostapd_append_wpa_key_mgmt
key_mgmt="$wpa_key_mgmt"

View File

@@ -0,0 +1,26 @@
Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c
===================================================================
--- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c
+++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c
@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho
sizeof(conf->bss[0]->iface));
} else if (os_strcmp(buf, "bridge") == 0) {
os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
+ if (!bss->wds_bridge[0])
+ os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
} else if (os_strcmp(buf, "vlan_bridge") == 0) {
os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
} else if (os_strcmp(buf, "wds_bridge") == 0) {
Index: hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c
===================================================================
--- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_drv_ops.c
+++ hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c
@@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d
return -1;
if (hapd->conf->wds_bridge[0])
bridge = hapd->conf->wds_bridge;
- else if (hapd->conf->bridge[0])
- bridge = hapd->conf->bridge;
return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
bridge, ifname_wds);
}

View File

@@ -1,5 +1,7 @@
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
Index: hostapd-2021-05-22-b102f19b/src/ap/ap_config.h
===================================================================
--- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_config.h
+++ hostapd-2021-05-22-b102f19b/src/ap/ap_config.h
@@ -278,6 +278,7 @@ struct hostapd_bss_config {
char iface[IFNAMSIZ + 1];
char bridge[IFNAMSIZ + 1];
@@ -8,8 +10,10 @@
char vlan_bridge[IFNAMSIZ + 1];
char wds_bridge[IFNAMSIZ + 1];
--- a/src/ap/x_snoop.c
+++ b/src/ap/x_snoop.c
Index: hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c
===================================================================
--- hostapd-2021-05-22-b102f19b.orig/src/ap/x_snoop.c
+++ hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c
@@ -31,14 +31,16 @@ int x_snoop_init(struct hostapd_data *ha
return -1;
}
@@ -53,12 +57,14 @@
if (l2 == NULL) {
wpa_printf(MSG_DEBUG,
"x_snoop: Failed to initialize L2 packet processing %s",
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho
sizeof(conf->bss[0]->iface));
} else if (os_strcmp(buf, "bridge") == 0) {
Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c
===================================================================
--- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c
+++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c
@@ -2359,6 +2359,8 @@ static int hostapd_config_fill(struct ho
os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
if (!bss->wds_bridge[0])
os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
+ } else if (os_strcmp(buf, "snoop_iface") == 0) {
+ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface));
} else if (os_strcmp(buf, "vlan_bridge") == 0) {

View File

@@ -630,7 +630,7 @@ mac80211_iw_interface_add() {
rc="$?"
}
[ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED
[ "$rc" != 0 ] && echo "Failed to create interface $ifname"
return $rc
}

View File

@@ -0,0 +1,33 @@
Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/reg.c
===================================================================
--- backports-20210222_001-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/reg.c
+++ backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/reg.c
@@ -170,6 +170,9 @@ int ath11k_regd_update(struct ath11k *ar
}
} else {
regd = ab->new_regd[pdev_id];
+ /* force update custom regdm to cfg80211 */
+ ar->hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+ wiphy_apply_custom_regulatory(ar->hw->wiphy, regd);
}
if (!regd) {
Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/wmi.c
===================================================================
--- backports-20210222_001-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/wmi.c
+++ backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/wmi.c
@@ -7212,12 +7212,12 @@ static int ath11k_reg_chan_list_event(st
* requested, i.e a default regd was already set during initialization
* and the regd coming from this event has a valid country info.
*/
- if (ab->default_regd[pdev_idx] &&
+/* if (ab->default_regd[pdev_idx] &&
!ath11k_reg_is_world_alpha((char *)
ab->default_regd[pdev_idx]->alpha2) &&
!ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
intersect = true;
-
+*/
regd = ath11k_reg_build_regd(ab, reg_info, intersect);
if (!regd) {
ath11k_warn(ab, "failed to build regd from reg_info\n");

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,22 @@
From da01b2ec475761de8ac92045329483f8a9cf7438 Mon Sep 17 00:00:00 2001
From bd7e19e3cc30bda8d0b0ae6f3d0c44425c6b7541 Mon Sep 17 00:00:00 2001
From: Rohan Nathi <rohan.nathi@indionetworks.com>
Date: Thu, 24 Jun 2021 13:48:45 +0000
Subject: [PATCH 25/43] ath79: add Support for Indio 305AC
Subject: [PATCH 01/22] ath79: add Support for Indio 305AC
Signed-off-by: Rohan Nathi <rohan.nathi@indionetworks.com>
---
.../ath79/dts/qca9531_indio_um-305ac.dts | 116 ++++++++++++++++++
.../ath79/dts/qca9531_indio_um-305ac.dts | 121 ++++++++++++++++++
.../etc/hotplug.d/firmware/11-ath10k-caldata | 1 +
target/linux/ath79/image/generic.mk | 11 ++
3 files changed, 128 insertions(+)
3 files changed, 133 insertions(+)
create mode 100755 target/linux/ath79/dts/qca9531_indio_um-305ac.dts
diff --git a/target/linux/ath79/dts/qca9531_indio_um-305ac.dts b/target/linux/ath79/dts/qca9531_indio_um-305ac.dts
new file mode 100755
index 0000000000..763fdcefa8
index 0000000000..3952c4ad2c
--- /dev/null
+++ b/target/linux/ath79/dts/qca9531_indio_um-305ac.dts
@@ -0,0 +1,116 @@
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qca953x.dtsi"
@@ -100,7 +100,12 @@ index 0000000000..763fdcefa8
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x050000 0xfa0000>;
+ reg = <0x050000 0xf90000>;
+ };
+
+ partition@fe0000 {
+ label = "certificates";
+ reg = <0xfe0000 0x010000>;
+ };
+
+ art: partition@ff0000 {

View File

@@ -1,7 +1,7 @@
From f7eed3ee6f7bb086a9bc0e049cc411d1bc98ed33 Mon Sep 17 00:00:00 2001
From 4d1fff5847b7550e185a87b230529cab68d21967 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sat, 4 Sep 2021 06:15:19 +0200
Subject: [PATCH 36/43] ipq4018: add EdgeCore SPW2AC1200 support
Subject: [PATCH 01/11] ipq4018: add EdgeCore SPW2AC1200 support
Signed-off-by: John Crispin <john@phrozen.org>
---
@@ -9,11 +9,11 @@ Signed-off-by: John Crispin <john@phrozen.org>
.../ipq40xx/base-files/etc/board.d/01_leds | 1 +
.../ipq40xx/base-files/etc/board.d/02_network | 1 +
.../etc/hotplug.d/firmware/11-ath10k-caldata | 2 +
.../base-files/lib/upgrade/platform.sh | 4 +-
.../base-files/lib/upgrade/platform.sh | 5 +
.../arm/boot/dts/qcom-ipq4018-spw2ac1200.dts | 332 ++++++++++++++++++
target/linux/ipq40xx/image/generic.mk | 13 +
.../901-arm-boot-add-dts-files.patch | 3 +-
8 files changed, 355 insertions(+), 2 deletions(-)
8 files changed, 357 insertions(+), 1 deletion(-)
create mode 100644 target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200.dts
diff --git a/package/boot/uboot-envtools/files/ipq40xx b/package/boot/uboot-envtools/files/ipq40xx
@@ -73,20 +73,28 @@ index c8943d3ba3..ad2946f636 100644
engenius,eap1300 |\
engenius,eap2200 |\
diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
index cbdd12c750..84abd181dc 100644
index cbdd12c750..62742f0697 100644
--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
@@ -76,7 +76,9 @@ platform_do_upgrade() {
tp-link,ec420-g1)
@@ -77,6 +77,7 @@ platform_do_upgrade() {
nand_do_upgrade "$1"
;;
- alfa-network,ap120c-ac)
+ alfa-network,ap120c-ac|\
+ edgecore,spw2ac1200)
alfa-network,ap120c-ac)
+ mkdir -p /var/lock/
part="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | sed -e 's/ .*$//')"
if [ "$part" = "rootfs1" ]; then
fw_setenv active 2 || exit 1
@@ -87,6 +88,10 @@ platform_do_upgrade() {
fi
nand_do_upgrade "$1"
;;
+ edgecore,spw2ac1200)
+ CI_UBIPART="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | sed -e 's/ .*$//')"
+ nand_do_upgrade "$1"
+ ;;
asus,map-ac2200)
CI_KERNPART="linux"
nand_do_upgrade "$1"
diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200.dts
new file mode 100644
index 0000000000..a152ba57f4

View File

@@ -0,0 +1,148 @@
From a0eb587ea9e4d905e1796c4f0d64fff9cd8a88f3 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 14 Oct 2021 15:13:56 +0200
Subject: [PATCH] spwlanpoe
Signed-off-by: John Crispin <john@phrozen.org>
---
package/boot/uboot-envtools/files/ipq40xx | 1 +
target/linux/ipq40xx/base-files/etc/board.d/01_leds | 1 +
.../linux/ipq40xx/base-files/etc/board.d/02_network | 1 +
.../etc/hotplug.d/firmware/11-ath10k-caldata | 2 ++
.../ipq40xx/base-files/lib/upgrade/platform.sh | 3 ++-
.../boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts | 6 ++++++
target/linux/ipq40xx/image/generic.mk | 13 +++++++++++++
.../patches-5.4/901-arm-boot-add-dts-files.patch | 3 ++-
8 files changed, 28 insertions(+), 2 deletions(-)
create mode 100644 target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts
diff --git a/package/boot/uboot-envtools/files/ipq40xx b/package/boot/uboot-envtools/files/ipq40xx
index fd7ad69eff..c51b40ab12 100644
--- a/package/boot/uboot-envtools/files/ipq40xx
+++ b/package/boot/uboot-envtools/files/ipq40xx
@@ -35,6 +35,7 @@ alfa-network,ap120c-ac |\
devolo,magic-2-wifi-next |\
edgecore,ecw5211 |\
edgecore,spw2ac1200 |\
+edgecore,spw2ac1200-lan-poe |\
glinet,gl-ap1300 |\
glinet,gl-b1300 |\
luma,wrtq-329acn |\
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
index d944d72184..5476dd5df6 100755
--- a/target/linux/ipq40xx/base-files/etc/board.d/01_leds
+++ b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
@@ -72,6 +72,7 @@ qxwlan,e2600ac-c2)
;;
edgecore,ecw5211 |\
edgecore,spw2ac1200 |\
+edgecore,spw2ac1200-lan-poe |\
cig,wf610d |\
zyxel,nbg6617 |\
zyxel,wre6606)
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network
index e4b009bf93..f533c39179 100755
--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network
+++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network
@@ -15,6 +15,7 @@ ipq40xx_setup_interfaces()
8dev,habanero-dvk|\
8dev,jalapeno|\
alfa-network,ap120c-ac|\
+ edgecore,spw2ac1200-lan-poe |\
engenius,emr3500|\
engenius,ens620ext|\
luma,wrtq-329acn|\
diff --git a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
index 97dd1b4039..e36821a596 100644
--- a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
+++ b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
@@ -105,6 +105,7 @@ case "$FIRMWARE" in
compex,wpj428 |\
edgecore,ecw5211 |\
edgecore,spw2ac1200 |\
+ edgecore,spw2ac1200-lan-poe |\
edgecore,oap100 |\
engenius,eap1300 |\
engenius,eap2200 |\
@@ -226,6 +227,7 @@ case "$FIRMWARE" in
compex,wpj428 |\
edgecore,ecw5211 |\
edgecore,spw2ac1200 |\
+ edgecore,spw2ac1200-lan-poe |\
edgecore,oap100 |\
engenius,eap1300 |\
engenius,eap2200 |\
diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
index 806b3edb66..d44a57c62a 100644
--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
@@ -90,7 +90,8 @@ platform_do_upgrade() {
fi
nand_do_upgrade "$1"
;;
- edgecore,spw2ac1200)
+ edgecore,spw2ac1200|\
+ edgecore,spw2ac1200-lan-poe)
CI_UBIPART="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | sed -e 's/ .*$//')"
nand_do_upgrade "$1"
;;
diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts
new file mode 100644
index 0000000000..1c2a2a8621
--- /dev/null
+++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-spw2ac1200-lan-poe.dts
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qcom-ipq4018-spw2ac1200.dts"
+/ {
+ compatible = "edgecore,spw2ac1200-lan-poe";
+};
diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk
index ae1e2e49cf..7e6118e61c 100644
--- a/target/linux/ipq40xx/image/generic.mk
+++ b/target/linux/ipq40xx/image/generic.mk
@@ -387,6 +387,19 @@ define Device/edgecore_spw2ac1200
endef
TARGET_DEVICES += edgecore_spw2ac1200
+define Device/edgecore_spw2ac1200-lan-poe
+ $(call Device/FitImage)
+ $(call Device/UbiFit)
+ DEVICE_VENDOR := Edgecore
+ DEVICE_MODEL := SPW2AC1200
+ SOC := qcom-ipq4018
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ DEVICE_DTS_CONFIG := config@ap.dk01.1-c2
+ DEVICE_PACKAGES := kmod-tpm-i2c-atmel kmod-usb-acm uboot-envtools kmod-usb-net kmod-usb-net-cdc-qmi uqmi
+endef
+TARGET_DEVICES += edgecore_spw2ac1200-lan-poe
+
define Device/edgecore_oap100
$(call Device/FitImage)
$(call Device/UbiFit)
diff --git a/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch
index 826e17b0e9..c4ecf62313 100644
--- a/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch
+++ b/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch
@@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
-@@ -837,11 +837,63 @@ dtb-$(CONFIG_ARCH_QCOM) += \
+@@ -837,11 +837,64 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8074-dragonboard.dtb \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
@@ -23,6 +23,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ qcom-ipq4018-eap1300.dtb \
+ qcom-ipq4018-ecw5211.dtb \
+ qcom-ipq4018-spw2ac1200.dtb \
++ qcom-ipq4018-spw2ac1200-lan-poe.dtb \
+ qcom-ipq4018-emd1.dtb \
+ qcom-ipq4018-emr3500.dtb \
+ qcom-ipq4018-ens620ext.dtb \
--
2.25.1

View File

@@ -1,311 +0,0 @@
From 558ca4df452ed2bdf8bbc9b82e4d23542a3cf66d Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sun, 5 Sep 2021 11:46:09 +0200
Subject: [PATCH] ipq5018
---
target/linux/ipq807x/Makefile | 2 +-
.../ipq807x/base-files/etc/board.d/02_network | 1 +
.../etc/hotplug.d/firmware/10-ath11k-caldata | 11 +--
.../base-files/lib/upgrade/platform.sh | 4 +-
target/linux/ipq807x/image/ipq50xx.mk | 10 +++
target/linux/ipq807x/ipq50xx/config-default | 84 +++++++++++++++++++
target/linux/ipq807x/ipq50xx/config-lowmem | 73 ++++++++++++++++
target/linux/ipq807x/ipq50xx/target.mk | 10 +++
8 files changed, 188 insertions(+), 7 deletions(-)
create mode 100644 target/linux/ipq807x/image/ipq50xx.mk
create mode 100644 target/linux/ipq807x/ipq50xx/config-default
create mode 100644 target/linux/ipq807x/ipq50xx/config-lowmem
create mode 100644 target/linux/ipq807x/ipq50xx/target.mk
diff --git a/target/linux/ipq807x/Makefile b/target/linux/ipq807x/Makefile
index 97c770df4a..abdb82ec5d 100644
--- a/target/linux/ipq807x/Makefile
+++ b/target/linux/ipq807x/Makefile
@@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=ipq807x
BOARDNAME:=Qualcomm Atheros AX
-SUBTARGETS:=ipq807x ipq60xx
+SUBTARGETS:=ipq807x ipq60xx ipq50xx
FEATURES:=squashfs ramdisk nand pcie usb
KERNELNAME:=Image dtbs
CPU_TYPE:=cortex-a7
diff --git a/target/linux/ipq807x/base-files/etc/board.d/02_network b/target/linux/ipq807x/base-files/etc/board.d/02_network
index ee9973f7a8..edf0e91143 100755
--- a/target/linux/ipq807x/base-files/etc/board.d/02_network
+++ b/target/linux/ipq807x/base-files/etc/board.d/02_network
@@ -24,6 +24,7 @@ qcom_setup_interfaces()
ucidef_set_interface_wan "eth5"
;;
cig,wf194c|\
+ qcom,ipq5018-mp03.3|\
sercomm,wallaby)
ucidef_set_interface_lan "eth0"
ucidef_set_interface_wan "eth1"
diff --git a/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata b/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata
index e64ea1a105..2b768e2f9b 100755
--- a/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata
+++ b/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata
@@ -47,7 +47,7 @@ case "$FIRMWARE" in
tplink,ex227|\
tplink,ex447|\
sercomm,wallaby)
- caldata_extract "0:ART" 0x1000 0x20000
+ caldata_extract "0:ART" 0x1000 0x20000
;;
esac
;;
@@ -58,21 +58,22 @@ case "$FIRMWARE" in
edgecore,eap101|\
qcom,ipq6018-cp01|\
xiaomi,ax1800)
- caldata_extract "0:ART" 0x1000 0x20000
+ caldata_extract "0:ART" 0x1000 0x10000
;;
esac
;;
ath11k/QCN9074/hw1.0/caldata_1.bin)
case "$board" in
qcom,ipq807x-hk14)
- caldata_extract "0:ART" 0x26800 0x20000
+ caldata_extract "0:ART" 0x26800 0x10000
;;
esac
;;
ath11k/QCN9074/hw1.0/caldata_2.bin)
case "$board" in
- qcom,ipq807x-hk14)
- caldata_extract "0:ART" 0x4C000 0x20000
+ qcom,ipq807x-hk14|\
+ qcom,ipq5018-mp03.3)
+ caldata_extract "0:ART" 0x4C000 0x10000
;;
esac
;;
diff --git a/target/linux/ipq807x/base-files/lib/upgrade/platform.sh b/target/linux/ipq807x/base-files/lib/upgrade/platform.sh
index 4943b6c406..8152ecb0ed 100755
--- a/target/linux/ipq807x/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ipq807x/base-files/lib/upgrade/platform.sh
@@ -30,7 +30,8 @@ platform_check_image() {
tplink,ex447|\
qcom,ipq6018-cp01|\
qcom,ipq807x-hk01|\
- qcom,ipq807x-hk14)
+ qcom,ipq807x-hk14|\
+ qcom,ipq5018-mp03.3)
[ "$magic_long" = "73797375" ] && return 0
;;
esac
@@ -52,6 +53,7 @@ platform_do_upgrade() {
qcom,ipq6018-cp01|\
qcom,ipq807x-hk01|\
qcom,ipq807x-hk14|\
+ qcom,ipq5018-mp03.3|\
tplink,ex447|\
tplink,ex227)
nand_upgrade_tar "$1"
diff --git a/target/linux/ipq807x/image/ipq50xx.mk b/target/linux/ipq807x/image/ipq50xx.mk
new file mode 100644
index 0000000000..f20d54190e
--- /dev/null
+++ b/target/linux/ipq807x/image/ipq50xx.mk
@@ -0,0 +1,10 @@
+KERNEL_LOADADDR := 0x41208000
+
+define Device/qcom_mp03_3
+ DEVICE_TITLE := Qualcomm Maple 03.3
+ DEVICE_DTS := qcom-ipq5018-mp03.3
+ SUPPORTED_DEVICES := qcom,ipq5018-mp03.3
+ DEVICE_PACKAGES := ath11k-wifi-qcom-ipq5018
+ DEVICE_DTS_CONFIG := config@mp03.3
+endef
+TARGET_DEVICES += qcom_mp03_3
diff --git a/target/linux/ipq807x/ipq50xx/config-default b/target/linux/ipq807x/ipq50xx/config-default
new file mode 100644
index 0000000000..b8e202c874
--- /dev/null
+++ b/target/linux/ipq807x/ipq50xx/config-default
@@ -0,0 +1,84 @@
+# CONFIG_AHCI_IPQ is not set
+CONFIG_ARCH_IPQ5018=y
+# CONFIG_DIAGFWD_BRIDGE_CODE is not set
+CONFIG_IPQ_ADSS_5018=y
+CONFIG_IPQ_APSS_5018=y
+CONFIG_IPQ_GCC_5018=y
+# CONFIG_NET_SWITCHDEV is not set
+CONFIG_NUM_ALT_PARTITION=16
+CONFIG_PINCTRL_IPQ5018=y
+# CONFIG_IPC_LOGGING is not set
+CONFIG_IPQ_SUBSYSTEM_DUMP=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_CSR=y
+CONFIG_CORESIGHT_CTI=y
+CONFIG_CORESIGHT_EVENT=y
+CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_CORESIGHT_LINKS_AND_SINKS=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_QCOM_REPLICATOR=y
+# CONFIG_INPUT_PM8941_PWRKEY is not set
+CONFIG_MDIO_QCA=y
+# CONFIG_CRYPTO_ALL_CASES is not set
+CONFIG_CRYPTO_DEV_QCOM_ICE=y
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_SHA512=y
+# CONFIG_CORESIGHT_QPDI is not set
+# CONFIG_CORESIGHT_SINK_ETBV10 is not set
+CONFIG_CORESIGHT_SINK_TPIU=y
+# CONFIG_CORESIGHT_SOURCE_DUMMY is not set
+CONFIG_CORESIGHT_SOURCE_ETM3X=y
+CONFIG_CORESIGHT_SOURCE_ETM4X=y
+# CONFIG_CORESIGHT_REMOTE_ETM is not set
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_TPDA=y
+CONFIG_CORESIGHT_TPDM=y
+# CONFIG_CORESIGHT_TPDM_DEFAULT_ENABLE is not set
+CONFIG_IIO=y
+# CONFIG_IIO_BUFFER is not set
+# CONFIG_IIO_TRIGGER is not set
+CONFIG_PCIE_DW_PLAT=y
+CONFIG_PHY_IPQ_UNIPHY_PCIE=y
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_PPS=y
+CONFIG_PTP_1588_CLOCK=y
+# CONFIG_DP83640_PHY is not set
+CONFIG_PWM_IPQ5018=y
+CONFIG_QCOM_APM=y
+CONFIG_QCOM_DCC=y
+# CONFIG_QCOM_SPMI_TEMP_ALARM is not set
+CONFIG_MMC_SDHCI_MSM_ICE=y
+CONFIG_USB_BAM=y
+CONFIG_MAILBOX=y
+# CONFIG_USB_QCOM_DIAG_BRIDGE is not set
+# CONFIG_USB_CONFIGFS_F_DIAG is not set
+# CONFIG_NF_IPV6_DUMMY_HEADER is not set
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_MTD_NAND_SERIAL=y
+CONFIG_PAGE_SCOPE_MULTI_PAGE_READ=y
+# CONFIG_RMNET_DATA_FC is not set
+CONFIG_CRYPTO_NO_ZERO_LEN_HASH=y
+CONFIG_CRYPTO_DISABLE_AES192_TEST=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_QTI_EUD=y
+CONFIG_USB_QCA_M31_PHY=y
+CONFIG_QGIC2_MSI=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_PWM_IPQ4019=y
+CONFIG_RMNET=y
+CONFIG_QCOM_QMI_RMNET=y
+CONFIG_QCOM_QMI_DFC=y
+CONFIG_QCOM_QMI_POWER_COLLAPSE=y
+CONFIG_RMNET_CTL=y
+CONFIG_RMNET_CTL_DEBUG=y
+CONFIG_SND_SOC_IPQ_LPASS=y
+CONFIG_SND_SOC_IPQ_LPASS_PCM_RAW=y
+# CONFIG_SND_SOC_IPQ_PCM_RAW is not set
diff --git a/target/linux/ipq807x/ipq50xx/config-lowmem b/target/linux/ipq807x/ipq50xx/config-lowmem
new file mode 100644
index 0000000000..b1b817ef6f
--- /dev/null
+++ b/target/linux/ipq807x/ipq50xx/config-lowmem
@@ -0,0 +1,73 @@
+# CONFIG_AHCI_IPQ is not set
+CONFIG_ARCH_IPQ5018=y
+# CONFIG_DIAGFWD_BRIDGE_CODE is not set
+CONFIG_IPQ_ADSS_5018=y
+CONFIG_IPQ_APSS_5018=y
+CONFIG_IPQ_GCC_5018=y
+# CONFIG_NET_SWITCHDEV is not set
+CONFIG_NUM_ALT_PARTITION=16
+CONFIG_PINCTRL_IPQ5018=y
+# CONFIG_IPC_LOGGING is not set
+CONFIG_IPQ_SUBSYSTEM_DUMP=y
+# CONFIG_SPS is not set
+# CONFIG_SPS_SUPPORT_NDP_BAM is not set
+# CONFIG_CORESIGHT is not set
+# CONFIG_INPUT_PM8941_PWRKEY is not set
+CONFIG_MDIO_QCA=y
+# CONFIG_CRYPTO_ALL_CASES is not set
+# CONFIG_CRYPTO_DEV_QCOM_ICE is not set
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_IIO is not set
+# CONFIG_IIO_BUFFER is not set
+# CONFIG_IIO_TRIGGER is not set
+CONFIG_PCIE_DW_PLAT=y
+CONFIG_PHY_IPQ_UNIPHY_PCIE=y
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_3G is not set
+# CONFIG_PPS is not set
+# CONFIG_PTP_1588_CLOCK is not set
+# CONFIG_DP83640_PHY is not set
+CONFIG_PWM_IPQ5018=y
+CONFIG_QCOM_APM=y
+# CONFIG_QCOM_DCC is not set
+# CONFIG_QCOM_SPMI_TEMP_ALARM is not set
+CONFIG_MMC_SDHCI_MSM_ICE=y
+CONFIG_USB_BAM=y
+CONFIG_MAILBOX=y
+# CONFIG_USB_QCOM_DIAG_BRIDGE is not set
+# CONFIG_USB_CONFIGFS_F_DIAG is not set
+# CONFIG_NF_IPV6_DUMMY_HEADER is not set
+# CONFIG_RMNET_DATA is not set
+# CONFIG_RMNET_DATA_DEBUG_PKT is not set
+CONFIG_MTD_NAND_SERIAL=y
+CONFIG_PAGE_SCOPE_MULTI_PAGE_READ=y
+# CONFIG_RMNET_DATA_FC is not set
+# CONFIG_CRYPTO_NO_ZERO_LEN_HASH is not set
+# CONFIG_CRYPTO_DISABLE_AES192_TEST is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_QTI_EUD=y
+CONFIG_USB_QCA_M31_PHY=y
+CONFIG_SQUASHFS_XZ=y
+# CONFIG_SQUASHFS_ZLIB is not set
+# CONFIG_JFFS2_LZMA is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_LZO_COMPRESS is not set
+# CONFIG_LZO_DECOMPRESS is not set
+CONFIG_XZ_DEC=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+CONFIG_XZ_DEC_ARM=y
+# CONFIG_XZ_DEC_ARMTHUMB is not set
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_LZO_COMPRESS is not set
+# CONFIG_LZO_DECOMPRESS is not set
+# CONFIG_CRYPTO is not set
+CONFIG_QGIC2_MSI=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
diff --git a/target/linux/ipq807x/ipq50xx/target.mk b/target/linux/ipq807x/ipq50xx/target.mk
new file mode 100644
index 0000000000..649f398ba6
--- /dev/null
+++ b/target/linux/ipq807x/ipq50xx/target.mk
@@ -0,0 +1,10 @@
+
+SUBTARGET:=ipq50xx
+BOARDNAME:=IPQ50XX
+CPU_TYPE:=cortex-a7
+
+DEFAULT_PACKAGES += ath11k-firmware-ipq50xx qca-nss-fw-ipq50xx
+
+define Target/Description
+ Build firmware image for IPQ50xx SoC devices.
+endef
--
2.25.1

14
profiles/cig_wf194c4.yml Normal file
View File

@@ -0,0 +1,14 @@
---
profile: cig_wf194c4
target: ipq807x
subtarget: ipq807x
description: Build image for the CIG WF194C4
image: bin/targets/ipq807x/ipq807x/openwrt-ipq807x-cig_wf194c4-squashfs-sysupgrade.tar
feeds:
- name: ipq807x
path: ../../feeds/ipq807x
include:
- wifi-ax
- ucentral-ap
diffconfig: |
CONFIG_KERNEL_IPQ_MEM_PROFILE=0

View File

@@ -0,0 +1,17 @@
---
profile: edgecore_spw2ac1200-lan-poe
target: ipq40xx
subtarget: generic
description: Build image for the Edgecore spw2ac1200
image: bin/targets/ipq40xx/generic/openwrt-ipq40xx-generic-edgecore_spw2ac1200-lan-poe-squashfs-nand-sysupgrade.bin
include:
- ucentral-ap
- container
packages:
- ath10k-firmware-qca4019-ct-htt
- ath10k-firmware-qca9888-ct-htt
- ath10k-firmware-qca9984-ct-htt
diffconfig: |
# CONFIG_PACKAGE_ath10k-firmware-qca4019-ct is not set
# CONFIG_PACKAGE_ath10k-firmware-qca9888-ct is not set
# CONFIG_PACKAGE_ath10k-firmware-qca9984-ct is not set

Some files were not shown because too many files have changed in this diff Show More