mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 01:22:25 +00:00
Compare commits
52 Commits
v2.2.0-rc2
...
release/v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3e3c9ea72 | ||
|
|
a3125e6ab2 | ||
|
|
63e8b90656 | ||
|
|
70f231d948 | ||
|
|
2983d9ca2b | ||
|
|
2283a64e57 | ||
|
|
1a3054218f | ||
|
|
7d26b55cb5 | ||
|
|
cd85723609 | ||
|
|
6d922da9b8 | ||
|
|
6b81555bb2 | ||
|
|
267157563e | ||
|
|
6505ca0a8f | ||
|
|
5cafdaea60 | ||
|
|
4a3d4f5609 | ||
|
|
3085dc78ef | ||
|
|
897ab17137 | ||
|
|
840319e24f | ||
|
|
00197d703e | ||
|
|
a290ad3764 | ||
|
|
972eea34eb | ||
|
|
851507921a | ||
|
|
b364ab3064 | ||
|
|
45143cc2c9 | ||
|
|
895e501b93 | ||
|
|
7d9594c3c8 | ||
|
|
485c689408 | ||
|
|
ec2e24e982 | ||
|
|
32f86e2d77 | ||
|
|
53e73b24de | ||
|
|
e57dad9009 | ||
|
|
01c3ce4fc7 | ||
|
|
6b3d2b8059 | ||
|
|
ba079bea9f | ||
|
|
f971f3a4d4 | ||
|
|
32524c19bd | ||
|
|
966353e747 | ||
|
|
37f30d95f8 | ||
|
|
e699bebac7 | ||
|
|
0e5ec91a12 | ||
|
|
3cad34e1b9 | ||
|
|
2c37a6983f | ||
|
|
330eead632 | ||
|
|
f1456f321a | ||
|
|
9152942d93 | ||
|
|
f202250a68 | ||
|
|
fad14af474 | ||
|
|
5a7bafede0 | ||
|
|
6738a933ab | ||
|
|
a46262aaaa | ||
|
|
2988180211 | ||
|
|
ec0d693d12 |
2
.github/workflows/build-dev.yml
vendored
2
.github/workflows/build-dev.yml
vendored
@@ -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
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
From 39af14f6e40bcb97772dcc0c03849fbf6aa0032b 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..d0ddec8f61 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..d0ddec8f61 100644
|
||||
-PKG_SOURCE_DATE:=2021-07-26
|
||||
-PKG_SOURCE_VERSION:=440eb0647708274cc8d7d9e7c2bb0cfdfba90023
|
||||
-PKG_MIRROR_HASH:=eed957036ab608fdc49bdf801fc5b4405fcd2a3a5e5d3343ec39898e156c10e9
|
||||
+PKG_SOURCE_DATE:=2021-09-01
|
||||
+PKG_SOURCE_VERSION:=e467e0ff44c00cdd722e7149baaa8706d44e657e
|
||||
+PKG_MIRROR_HASH:=cde5c1c1609c29f24171dcd97d2264e28a6dfb724e25f4bd3c2be351b6dd4f10
|
||||
+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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
From 705ea724f1dc4083665746a1cf4c9b0f317667ec 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..5f5b89370d
|
||||
--- /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 = $(PKG_BUILD_DIR)/scripts/bpf_helpers_doc.py
|
||||
+
|
||||
+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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -22,6 +22,7 @@ let keys = {
|
||||
nasmac: false,
|
||||
macauth: false,
|
||||
macpassword: false,
|
||||
uamsecret: false,
|
||||
};
|
||||
|
||||
function get_value(key, value) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
17
feeds/tip/luci/luci-mod-ucentral/Makefile
Normal file
17
feeds/tip/luci/luci-mod-ucentral/Makefile
Normal 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
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
@@ -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
|
||||
});
|
||||
@@ -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
|
||||
});
|
||||
@@ -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
|
||||
});
|
||||
@@ -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
|
||||
});
|
||||
426
feeds/tip/luci/luci-mod-ucentral/po/de/ucentral.po
Normal file
426
feeds/tip/luci/luci-mod-ucentral/po/de/ucentral.po
Normal 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"
|
||||
385
feeds/tip/luci/luci-mod-ucentral/po/templates/ucentral.pot
Normal file
385
feeds/tip/luci/luci-mod-ucentral/po/templates/ucentral.pot
Normal 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 ""
|
||||
33
feeds/tip/luci/luci-mod-ucentral/root/sbin/certupdate
Executable file
33
feeds/tip/luci/luci-mod-ucentral/root/sbin/certupdate
Executable 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
|
||||
15
feeds/tip/luci/luci-mod-ucentral/root/sbin/profileupdate
Executable file
15
feeds/tip/luci/luci-mod-ucentral/root/sbin/profileupdate
Executable 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
|
||||
@@ -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" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
feeds/tip/luci/luci-theme-ucentral/Makefile
Normal file
14
feeds/tip/luci/luci-theme-ucentral/Makefile
Normal 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
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
});
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -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 |
@@ -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 |
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
294
feeds/tip/luci/luci.mk
Normal 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))))
|
||||
@@ -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
|
||||
|
||||
52
feeds/ucentral/qosify/Makefile
Normal file
52
feeds/ucentral/qosify/Makefile
Normal file
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# 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))
|
||||
|
||||
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) $(PKG_BUILD_DIR)/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))
|
||||
BIN
feeds/ucentral/qosify/files/qosify-bpf.o
Normal file
BIN
feeds/ucentral/qosify/files/qosify-bpf.o
Normal file
Binary file not shown.
17
feeds/ucentral/qosify/files/qosify-defaults.conf
Normal file
17
feeds/ucentral/qosify/files/qosify-defaults.conf
Normal 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
|
||||
28
feeds/ucentral/qosify/files/qosify.conf
Normal file
28
feeds/ucentral/qosify/files/qosify.conf
Normal 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 0
|
||||
|
||||
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
|
||||
|
||||
2
feeds/ucentral/qosify/files/qosify.hotplug
Normal file
2
feeds/ucentral/qosify/files/qosify.hotplug
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
ubus call qosify check_devices
|
||||
103
feeds/ucentral/qosify/files/qosify.init
Normal file
103
feeds/ucentral/qosify/files/qosify.init
Normal 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" defaults
|
||||
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
|
||||
}
|
||||
15
feeds/ucentral/qosify/src/CMakeLists.txt
Normal file
15
feeds/ucentral/qosify/src/CMakeLists.txt
Normal 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}
|
||||
)
|
||||
557
feeds/ucentral/qosify/src/interface.c
Normal file
557
feeds/ucentral/qosify/src/interface.c
Normal 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);
|
||||
}
|
||||
|
||||
126
feeds/ucentral/qosify/src/loader.c
Normal file
126
feeds/ucentral/qosify/src/loader.c
Normal 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;
|
||||
}
|
||||
71
feeds/ucentral/qosify/src/main.c
Normal file
71
feeds/ucentral/qosify/src/main.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#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_ubus_stop();
|
||||
qosify_iface_stop();
|
||||
|
||||
uloop_done();
|
||||
|
||||
return 0;
|
||||
}
|
||||
575
feeds/ucentral/qosify/src/map.c
Normal file
575
feeds/ucentral/qosify/src/map.c
Normal 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);
|
||||
}
|
||||
435
feeds/ucentral/qosify/src/qosify-bpf.c
Normal file
435
feeds/ucentral/qosify/src/qosify-bpf.c
Normal file
@@ -0,0 +1,435 @@
|
||||
#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)
|
||||
return;
|
||||
|
||||
*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";
|
||||
26
feeds/ucentral/qosify/src/qosify-bpf.h
Normal file
26
feeds/ucentral/qosify/src/qosify-bpf.h
Normal 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
|
||||
83
feeds/ucentral/qosify/src/qosify.h
Normal file
83
feeds/ucentral/qosify/src/qosify.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#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 {
|
||||
uint32_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);
|
||||
void qosify_ubus_stop(void);
|
||||
int qosify_ubus_check_interface(const char *name, char *ifname, int ifname_len);
|
||||
|
||||
#endif
|
||||
369
feeds/ucentral/qosify/src/ubus.c
Normal file
369
feeds/ucentral/qosify/src/ubus.c
Normal file
@@ -0,0 +1,369 @@
|
||||
#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_udp", BLOBMSG_TYPE_STRING },
|
||||
[CL_CONFIG_DSCP_TCP] = { "dscp_default_tcp", 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;
|
||||
}
|
||||
|
||||
void qosify_ubus_stop(void)
|
||||
{
|
||||
ubus_auto_shutdown(&conn);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci delete qosify.wan
|
||||
uci delete qosify.wandev
|
||||
uci set qosify.@defaults[-1].defaults=/tmp/qosify.conf
|
||||
@@ -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>
|
||||
|
||||
@@ -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))
|
||||
|
||||
1133
feeds/ucentral/ucode/patches/100-resolv.patch
Normal file
1133
feeds/ucentral/ucode/patches/100-resolv.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
BIN
feeds/wifi-ax/ath11k-wifi/board-cig-wf194c4.bin.IPQ8074
Normal file
BIN
feeds/wifi-ax/ath11k-wifi/board-cig-wf194c4.bin.IPQ8074
Normal file
Binary file not shown.
Binary file not shown.
BIN
feeds/wifi-ax/ath11k-wifi/board-wallys-dr6018.bin.IPQ6018
Normal file
BIN
feeds/wifi-ax/ath11k-wifi/board-wallys-dr6018.bin.IPQ6018
Normal file
Binary file not shown.
@@ -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"
|
||||
|
||||
|
||||
26
feeds/wifi-ax/hostapd/patches/711-wds_bridge_force.patch
Normal file
26
feeds/wifi-ax/hostapd/patches/711-wds_bridge_force.patch
Normal 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);
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
33
feeds/wifi-ax/mac80211/patches/pending/217-regdb.patch
Normal file
33
feeds/wifi-ax/mac80211/patches/pending/217-regdb.patch
Normal 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
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
14
profiles/cig_wf194c4.yml
Normal 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
|
||||
17
profiles/edgecore_spw2ac1200-lan-poe.yml
Normal file
17
profiles/edgecore_spw2ac1200-lan-poe.yml
Normal 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
|
||||
@@ -5,4 +5,5 @@ feeds:
|
||||
path: ../../feeds/openflow
|
||||
|
||||
packages:
|
||||
- kmod-veth
|
||||
- openvswitch
|
||||
|
||||
@@ -16,7 +16,7 @@ packages:
|
||||
- ip-bridge
|
||||
- maverick
|
||||
- ratelimit
|
||||
- sqm-scripts
|
||||
- qosify
|
||||
- tip-defaults
|
||||
- ucentral-client
|
||||
- ucentral-event
|
||||
|
||||
@@ -16,7 +16,7 @@ packages:
|
||||
- maverick
|
||||
- ratelimit
|
||||
- rtty-openssl
|
||||
- sqm-scripts
|
||||
- qosify
|
||||
- tip-defaults
|
||||
- ucentral-client
|
||||
- ucentral-event
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user