Merge commit 'de7e69dbe3865f0d70238203d453f0f84f059ddf' as 'luci-app-einat'
This commit is contained in:
commit
bb6c79b701
luci-app-einat
19
luci-app-einat/.prepare.sh
Executable file
19
luci-app-einat/.prepare.sh
Executable file
|
@ -0,0 +1,19 @@
|
|||
PKG_NAME="$1"
|
||||
CURDIR="$2"
|
||||
PKG_BUILD_DIR="$3"
|
||||
|
||||
if [ -d "$CURDIR/.git" ]; then
|
||||
config="$CURDIR/.git/config"
|
||||
else
|
||||
config="$(sed "s|^gitdir:\s*|$CURDIR/|;s|$|/config|" "$CURDIR/.git")"
|
||||
fi
|
||||
[ -n "$(sed -En '/^\[remote /{h;:top;n;/^\[/b;s,(https?://gitcode\.(com|net)),\1,;T top;H;x;s|\n\s*|: |;p;}' "$config")" ] && {
|
||||
for d in luasrc ucode htdocs root src; do
|
||||
rm -rf "$PKG_BUILD_DIR"/$d
|
||||
done
|
||||
mkdir -p "$PKG_BUILD_DIR"/htdocs/luci-static/resources/view
|
||||
touch "$PKG_BUILD_DIR"/htdocs/luci-static/resources/view/$PKG_NAME.js
|
||||
mkdir -p "$PKG_BUILD_DIR"/root/usr/share/luci/menu.d
|
||||
touch "$PKG_BUILD_DIR"/root/usr/share/luci/menu.d/$PKG_NAME.json
|
||||
}
|
||||
exit 0
|
21
luci-app-einat/LICENSE
Normal file
21
luci-app-einat/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Anya Lin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
23
luci-app-einat/Makefile
Normal file
23
luci-app-einat/Makefile
Normal file
|
@ -0,0 +1,23 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (C) 2024-2025 Anya Lin <https://github.com/muink>
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_NAME:=luci-app-einat
|
||||
|
||||
LUCI_TITLE:=LuCI Support for einat
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+einat-ebpf
|
||||
|
||||
LUCI_DESCRIPTION:=eBPF-based Endpoint-Independent NAT
|
||||
|
||||
PKG_MAINTAINER:=Anya Lin <hukk1996@gmail.com>
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_UNPACK=$(CURDIR)/.prepare.sh $(PKG_NAME) $(CURDIR) $(PKG_BUILD_DIR)
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
40
luci-app-einat/README.md
Normal file
40
luci-app-einat/README.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
# luci-app-einat
|
||||
|
||||
> [einat-ebpf][] project is an eBPF application implements an "Endpoint-Independent Mapping" and "Endpoint-Independent Filtering" NAT(network address translation) on TC egress and ingress hooks.
|
||||
|
||||
## Depends
|
||||
|
||||
1. [openwrt-einat-ebpf][]
|
||||
|
||||
## Releases
|
||||
You can find the prebuilt-ipks [here](https://fantastic-packages.github.io/packages/)
|
||||
|
||||
## Build
|
||||
|
||||
```shell
|
||||
# Take the x86_64 platform as an example
|
||||
tar xjf openwrt-sdk-23.05.3-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
# Go to the SDK root dir
|
||||
cd OpenWrt-sdk-*-x86_64_*
|
||||
# First run to generate a .config file
|
||||
make menuconfig
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
# Get Makefile
|
||||
git clone --depth 1 --branch master --single-branch --no-checkout https://github.com/muink/luci-app-einat.git package/luci-app-einat
|
||||
pushd package/luci-app-einat
|
||||
umask 022
|
||||
git checkout
|
||||
popd
|
||||
# Select the package LuCI -> Applications -> luci-app-einat
|
||||
make menuconfig
|
||||
# Start compiling
|
||||
make package/luci-app-einat/compile V=99
|
||||
```
|
||||
|
||||
[einat-ebpf]: https://github.com/EHfive/einat-ebpf
|
||||
[openwrt-einat-ebpf]: https://github.com/muink/openwrt-einat-ebpf
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT license
|
183
luci-app-einat/htdocs/luci-static/resources/view/einat.js
Normal file
183
luci-app-einat/htdocs/luci-static/resources/view/einat.js
Normal file
|
@ -0,0 +1,183 @@
|
|||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require uci';
|
||||
'require ui';
|
||||
'require rpc';
|
||||
'require poll';
|
||||
'require view';
|
||||
'require network';
|
||||
'require tools.widgets as widgets';
|
||||
|
||||
const conf = 'einat';
|
||||
const instance = 'einat';
|
||||
|
||||
const callServiceList = rpc.declare({
|
||||
object: 'service',
|
||||
method: 'list',
|
||||
params: ['name'],
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
const callRcInit = rpc.declare({
|
||||
object: 'rc',
|
||||
method: 'init',
|
||||
params: ['name', 'action']
|
||||
});
|
||||
|
||||
const callGetFeatures = rpc.declare({
|
||||
object: 'luci.einat',
|
||||
method: 'get_features',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
function getServiceStatus() {
|
||||
return L.resolveDefault(callServiceList(conf), {})
|
||||
.then((res) => {
|
||||
let isrunning = false;
|
||||
try {
|
||||
isrunning = res[conf]['instances'][instance]['running'];
|
||||
} catch (e) { }
|
||||
return isrunning;
|
||||
});
|
||||
}
|
||||
|
||||
function handleAction(action, ev) {
|
||||
return callRcInit("einat", action).then((ret) => {
|
||||
if (ret)
|
||||
throw _('Command failed');
|
||||
|
||||
return true;
|
||||
}).catch((e) => {
|
||||
ui.addNotification(null, E('p', _('Failed to execute "/etc/init.d/%s %s" action: %s').format("einat", action, e)));
|
||||
});
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load() {
|
||||
return Promise.all([
|
||||
getServiceStatus(),
|
||||
L.resolveDefault(fs.stat('/usr/bin/einat'), null),
|
||||
callGetFeatures(),
|
||||
uci.load('einat')
|
||||
]);
|
||||
},
|
||||
|
||||
poll_status(nodes, stat) {
|
||||
const isRunning = stat[0];
|
||||
let view = nodes.querySelector('#service_status');
|
||||
|
||||
if (isRunning) {
|
||||
view.innerHTML = "<span style=\"color:green;font-weight:bold\">" + instance + " - " + _("SERVER RUNNING") + "</span>";
|
||||
} else {
|
||||
view.innerHTML = "<span style=\"color:red;font-weight:bold\">" + instance + " - " + _("SERVER NOT RUNNING") + "</span>";
|
||||
}
|
||||
return;
|
||||
},
|
||||
|
||||
render(res) {
|
||||
const isRunning = res[0];
|
||||
const has_einat = res[1] ? res[1].path : null;
|
||||
const features = res[2];
|
||||
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('einat', _('einat-ebpf'), _('eBPF-based Endpoint-Independent NAT'));
|
||||
|
||||
s = m.section(form.NamedSection, '_status');
|
||||
s.anonymous = true;
|
||||
s.render = function(section_id) {
|
||||
return E('div', { class: 'cbi-section' }, [
|
||||
E('div', { id: 'service_status' }, _('Collecting data ...'))
|
||||
]);
|
||||
};
|
||||
|
||||
s = m.section(form.NamedSection, 'config', instance);
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.Button, '_reload', _('Reload'));
|
||||
o.inputtitle = _('Reload');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = function() {
|
||||
return handleAction('reload');
|
||||
};
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enable'));
|
||||
o.default = o.disabled;
|
||||
o.rmempty = false;
|
||||
if (! has_einat) {
|
||||
o.description = _('To enable you need install <b>einat-ebpf</b> first');
|
||||
o.readonly = true;
|
||||
}
|
||||
|
||||
o = s.option(form.ListValue, 'bpf_log_level', _('BPF tracing log level'));
|
||||
o.default = '0';
|
||||
o.value('0', 'disable - ' + _('Disable'));
|
||||
o.value('1', 'error - ' + _('Error'));
|
||||
o.value('2', 'warn - ' + _('Warn'));
|
||||
o.value('3', 'info - ' + _('Info'));
|
||||
o.value('4', 'debug - ' + _('Debug'));
|
||||
o.value('5', 'trace - ' + _('Trace'));
|
||||
|
||||
o = s.option(form.ListValue, 'bpf_loader', _('BPF loading backend'));
|
||||
o.value('', _('Default'));
|
||||
if (features.features.includes('aya'))
|
||||
o.value('aya', _('aya'));
|
||||
if (features.features.includes('libbpf'))
|
||||
o.value('libbpf', _('libbpf'));
|
||||
|
||||
o = s.option(form.Flag, 'nat44', _('NAT44'));
|
||||
o.default = o.disabled;
|
||||
o.rmempty = false;
|
||||
|
||||
//o = s.option(form.Flag, 'nat66', _('NAT66'));
|
||||
//o.default = o.disabled;
|
||||
//o.rmempty = false;
|
||||
|
||||
o = s.option(widgets.DeviceSelect, 'ifname', _('External interface'));
|
||||
o.multiple = false;
|
||||
o.noaliases = true;
|
||||
o.nobridges = true;
|
||||
o.nocreate = true;
|
||||
|
||||
o = s.option(form.Value, 'ports', _('External TCP/UDP port ranges'),
|
||||
_('Please avoid conflicts with external ports used by other applications'));
|
||||
o.datatype = 'portrange';
|
||||
o.placeholder = '20000-29999';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.option(widgets.NetworkSelect, 'internal_ifaces', _('Internal interfaces'),
|
||||
_('Perform source NAT for these internal networks only.'));
|
||||
o.multiple = true;
|
||||
o.nocreate = true;
|
||||
|
||||
o = s.option(form.DynamicList, 'internal_subnets', _('Internal subnets'),
|
||||
_('Perform source NAT for these internal networks only.'));
|
||||
o.datatype = 'cidr';
|
||||
o.placeholder = '192.168.0.0/16';
|
||||
|
||||
o = s.option(form.Flag, 'hairpin_enabled', _('Enable hairpin'),
|
||||
_('May conflict with other policy routing-based applications'));
|
||||
o.default = o.disabled;
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(widgets.DeviceSelect, 'hairpinif', _('Hairpin internal interfaces'));
|
||||
o.multiple = true;
|
||||
o.noaliases = true;
|
||||
o.nobridges = false;
|
||||
o.nocreate = true;
|
||||
o.depends('hairpin_enabled', '1');
|
||||
o.rmempty = true;
|
||||
o.retain = true;
|
||||
|
||||
return m.render()
|
||||
.then(L.bind(function(m, nodes) {
|
||||
poll.add(L.bind(function() {
|
||||
return Promise.all([
|
||||
getServiceStatus()
|
||||
]).then(L.bind(this.poll_status, this, nodes));
|
||||
}, this), 3);
|
||||
return nodes;
|
||||
}, this, m));
|
||||
}
|
||||
});
|
133
luci-app-einat/po/templates/einat.pot
Normal file
133
luci-app-einat/po/templates/einat.pot
Normal file
|
@ -0,0 +1,133 @@
|
|||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:114
|
||||
msgid "BPF loading backend"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:105
|
||||
msgid "BPF tracing log level"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:83
|
||||
msgid "Collecting data ..."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:42
|
||||
msgid "Command failed"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:111
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:115
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:107
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:97
|
||||
msgid "Enable"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:149
|
||||
msgid "Enable hairpin"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:108
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:133
|
||||
msgid "External TCP/UDP port ranges"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:127
|
||||
msgid "External interface"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:46
|
||||
msgid "Failed to execute \"/etc/init.d/%s %s\" action: %s"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-app-einat.json:3
|
||||
msgid "Grant access to LuCI app einat"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:154
|
||||
msgid "Hairpin internal interfaces"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:110
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:139
|
||||
msgid "Internal interfaces"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:144
|
||||
msgid "Internal subnets"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:150
|
||||
msgid "May conflict with other policy routing-based applications"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:119
|
||||
msgid "NAT44"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:140
|
||||
#: htdocs/luci-static/resources/view/einat.js:145
|
||||
msgid "Perform source NAT for these internal networks only."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:134
|
||||
msgid "Please avoid conflicts with external ports used by other applications"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:90
|
||||
#: htdocs/luci-static/resources/view/einat.js:91
|
||||
msgid "Reload"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:66
|
||||
msgid "SERVER NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:64
|
||||
msgid "SERVER RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:101
|
||||
msgid "To enable you need install <b>einat-ebpf</b> first"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:112
|
||||
msgid "Trace"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:109
|
||||
msgid "Warn"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:116
|
||||
msgid "aya"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:77
|
||||
msgid "eBPF-based Endpoint-Independent NAT"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:77
|
||||
#: root/usr/share/luci/menu.d/luci-app-einat.json:3
|
||||
msgid "einat-ebpf"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:117
|
||||
msgid "libbpf"
|
||||
msgstr ""
|
142
luci-app-einat/po/zh_Hans/einat.po
Normal file
142
luci-app-einat/po/zh_Hans/einat.po
Normal file
|
@ -0,0 +1,142 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2024-05-10 12:23+0000\n"
|
||||
"Last-Translator: Anya Lin <muink@users.noreply.github.com>\n"
|
||||
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
|
||||
"openwrt/luciapplicationseinat/zh_Hans/>\n"
|
||||
"Language: zh_Hans\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 4.18-dev\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:114
|
||||
msgid "BPF loading backend"
|
||||
msgstr "BPF 加载后端"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:105
|
||||
msgid "BPF tracing log level"
|
||||
msgstr "BPF 追踪日志等级"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:83
|
||||
msgid "Collecting data ..."
|
||||
msgstr "正在收集数据..."
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:42
|
||||
msgid "Command failed"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:111
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:115
|
||||
msgid "Default"
|
||||
msgstr "默认"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:107
|
||||
msgid "Disable"
|
||||
msgstr "禁用"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:97
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:149
|
||||
msgid "Enable hairpin"
|
||||
msgstr "启用 Hairpin"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:108
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:133
|
||||
msgid "External TCP/UDP port ranges"
|
||||
msgstr "外部 TCP/UDP 端口范围"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:127
|
||||
msgid "External interface"
|
||||
msgstr "外部接口"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:46
|
||||
msgid "Failed to execute \"/etc/init.d/%s %s\" action: %s"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-app-einat.json:3
|
||||
msgid "Grant access to LuCI app einat"
|
||||
msgstr "授予访问 LuCI 应用 einat 的权限"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:154
|
||||
msgid "Hairpin internal interfaces"
|
||||
msgstr "Hairpin 内部接口"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:110
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:139
|
||||
msgid "Internal interfaces"
|
||||
msgstr "内部接口"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:144
|
||||
msgid "Internal subnets"
|
||||
msgstr "内部子网"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:150
|
||||
msgid "May conflict with other policy routing-based applications"
|
||||
msgstr "可能与其他基于策略路由的应用程序发生冲突"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:119
|
||||
msgid "NAT44"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:140
|
||||
#: htdocs/luci-static/resources/view/einat.js:145
|
||||
msgid "Perform source NAT for these internal networks only."
|
||||
msgstr "仅对这些内部网络执行 SNAT。"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:134
|
||||
msgid "Please avoid conflicts with external ports used by other applications"
|
||||
msgstr "请避免与其他应用使用的外部端口冲突"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:90
|
||||
#: htdocs/luci-static/resources/view/einat.js:91
|
||||
msgid "Reload"
|
||||
msgstr "重新载入"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:66
|
||||
msgid "SERVER NOT RUNNING"
|
||||
msgstr "服务器未运行"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:64
|
||||
msgid "SERVER RUNNING"
|
||||
msgstr "服务器运行中"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:101
|
||||
msgid "To enable you need install <b>einat-ebpf</b> first"
|
||||
msgstr "要启用您需要先安装 <b>einat-ebpf</b>"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:112
|
||||
msgid "Trace"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:109
|
||||
msgid "Warn"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:116
|
||||
msgid "aya"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:77
|
||||
msgid "eBPF-based Endpoint-Independent NAT"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:77
|
||||
#: root/usr/share/luci/menu.d/luci-app-einat.json:3
|
||||
msgid "einat-ebpf"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:117
|
||||
msgid "libbpf"
|
||||
msgstr ""
|
142
luci-app-einat/po/zh_Hant/einat.po
Normal file
142
luci-app-einat/po/zh_Hant/einat.po
Normal file
|
@ -0,0 +1,142 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2024-05-10 12:23+0000\n"
|
||||
"Last-Translator: Anya Lin <muink@users.noreply.github.com>\n"
|
||||
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
|
||||
"openwrt/luciapplicationseinat/zh_Hant/>\n"
|
||||
"Language: zh_Hant\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 4.18-dev\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:114
|
||||
msgid "BPF loading backend"
|
||||
msgstr "BPF 載入後端"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:105
|
||||
msgid "BPF tracing log level"
|
||||
msgstr "BPF 追蹤日誌級別"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:83
|
||||
msgid "Collecting data ..."
|
||||
msgstr "正在收集數據..."
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:42
|
||||
msgid "Command failed"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:111
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:115
|
||||
msgid "Default"
|
||||
msgstr "預設"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:107
|
||||
msgid "Disable"
|
||||
msgstr "禁用"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:97
|
||||
msgid "Enable"
|
||||
msgstr "啟用"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:149
|
||||
msgid "Enable hairpin"
|
||||
msgstr "啟用 Hairpin"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:108
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:133
|
||||
msgid "External TCP/UDP port ranges"
|
||||
msgstr "外部 TCP/UDP 埠範圍"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:127
|
||||
msgid "External interface"
|
||||
msgstr "外部介面"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:46
|
||||
msgid "Failed to execute \"/etc/init.d/%s %s\" action: %s"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-app-einat.json:3
|
||||
msgid "Grant access to LuCI app einat"
|
||||
msgstr "授予訪問 LuCI 應用 einat 的權限"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:154
|
||||
msgid "Hairpin internal interfaces"
|
||||
msgstr "Hairpin 內部介面"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:110
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:139
|
||||
msgid "Internal interfaces"
|
||||
msgstr "內部介面"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:144
|
||||
msgid "Internal subnets"
|
||||
msgstr "內部子網"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:150
|
||||
msgid "May conflict with other policy routing-based applications"
|
||||
msgstr "可能與其他基於策略路由的應用程式發生衝突"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:119
|
||||
msgid "NAT44"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:140
|
||||
#: htdocs/luci-static/resources/view/einat.js:145
|
||||
msgid "Perform source NAT for these internal networks only."
|
||||
msgstr "僅對這些內部網路執行 SNAT。"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:134
|
||||
msgid "Please avoid conflicts with external ports used by other applications"
|
||||
msgstr "請避免與其他應用程式使用的外部連接埠衝突"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:90
|
||||
#: htdocs/luci-static/resources/view/einat.js:91
|
||||
msgid "Reload"
|
||||
msgstr "重新載入"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:66
|
||||
msgid "SERVER NOT RUNNING"
|
||||
msgstr "伺服器未運行"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:64
|
||||
msgid "SERVER RUNNING"
|
||||
msgstr "伺服器運行中"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:101
|
||||
msgid "To enable you need install <b>einat-ebpf</b> first"
|
||||
msgstr "要啟用您需要先安裝 <b>einat-ebpf</b>"
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:112
|
||||
msgid "Trace"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:109
|
||||
msgid "Warn"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:116
|
||||
msgid "aya"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:77
|
||||
msgid "eBPF-based Endpoint-Independent NAT"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:77
|
||||
#: root/usr/share/luci/menu.d/luci-app-einat.json:3
|
||||
msgid "einat-ebpf"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/einat.js:117
|
||||
msgid "libbpf"
|
||||
msgstr ""
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"admin/network/einat": {
|
||||
"title": "einat-ebpf",
|
||||
"order": 60,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "einat"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-einat" ]
|
||||
}
|
||||
}
|
||||
}
|
21
luci-app-einat/root/usr/share/rpcd/acl.d/luci-app-einat.json
Normal file
21
luci-app-einat/root/usr/share/rpcd/acl.d/luci-app-einat.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"luci-app-einat": {
|
||||
"description": "Grant access to LuCI app einat",
|
||||
"read": {
|
||||
"file": {
|
||||
"/etc/init.d/einat reload": [ "exec" ]
|
||||
},
|
||||
"ubus": {
|
||||
"service": [ "list" ],
|
||||
"luci.einat": [ "*" ]
|
||||
},
|
||||
"uci": ["einat"]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"rc": [ "init" ]
|
||||
},
|
||||
"uci": ["einat"]
|
||||
}
|
||||
}
|
||||
}
|
38
luci-app-einat/root/usr/share/rpcd/ucode/luci.einat
Normal file
38
luci-app-einat/root/usr/share/rpcd/ucode/luci.einat
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/ucode
|
||||
|
||||
'use strict';
|
||||
|
||||
import { access, popen } from 'fs';
|
||||
|
||||
const methods = {
|
||||
get_features: {
|
||||
call: function() {
|
||||
let features = {
|
||||
version: null,
|
||||
features: [],
|
||||
build_features: []
|
||||
};
|
||||
|
||||
const fd = popen('/usr/bin/einat -v');
|
||||
if (fd) {
|
||||
for (let line = fd.read('line'); length(line); line = fd.read('line')) {
|
||||
let ver = match(trim(line), /version: (\S+)/);
|
||||
if (ver)
|
||||
features.version = ver[1];
|
||||
let feats = match(trim(line), /features: (\S+)/);
|
||||
if (feats)
|
||||
features.features = split(feats[1], ',');
|
||||
let build_feats = match(trim(line), /build_features: (\S+)/);
|
||||
if (build_feats)
|
||||
features.build_features = split(build_feats[1], ',');
|
||||
}
|
||||
|
||||
fd.close();
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { 'luci.einat': methods };
|
Loading…
Reference in a new issue