mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-26 18:52:51 +08:00
⛄ Sync 2026-07-03 20:40:27
This commit is contained in:
1 parent
2b1b1f1ad7
commit
40213156af
26 files changed
+2592
-5
No files matched your search
@@ -0,0 +1,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=MWAN3 Ledhelper simple webUI
|
||||
LUCI_DEPENDS:=+luci-app-mwan3-nft +mwan3-ledhelper-nft
|
||||
PKG_LICENSE:=GPLv3
|
||||
PKG_VERSION:=0.0.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -0,0 +1,110 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require view';
|
||||
'require uci';
|
||||
'require rpc';
|
||||
'require ui';
|
||||
'require network';
|
||||
'require tools.widgets as widgets'
|
||||
|
||||
var callLEDs = rpc.declare({
|
||||
object: 'luci',
|
||||
method: 'getLEDs',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
callLEDs(),
|
||||
L.resolveDefault(fs.list('/www' + L.resource('view/system/led-trigger')), []),
|
||||
// load config mwan3
|
||||
fs.read('/etc/config/mwan3').catch(function(err) { return ''; })
|
||||
]).then(function(data) {
|
||||
var plugins = data[1];
|
||||
var mwan3Config = data[2];
|
||||
var tasks = [];
|
||||
|
||||
// parce ifaces mwan3 config
|
||||
var mwan3Interfaces = [];
|
||||
if (mwan3Config) {
|
||||
var lines = mwan3Config.split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i].trim();
|
||||
var match = line.match(/^config interface '([^']+)'/);
|
||||
if (match) {
|
||||
mwan3Interfaces.push(match[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < plugins.length; i++) {
|
||||
var m = plugins[i].name.match(/^(.+)\.js$/);
|
||||
|
||||
if (plugins[i].type != 'file' || m == null)
|
||||
continue;
|
||||
|
||||
tasks.push(L.require('view.system.led-trigger.' + m[1]).then(L.bind(function(name){
|
||||
return L.resolveDefault(L.require('view.system.led-trigger.' + name)).then(function(form) {
|
||||
return {
|
||||
name: name,
|
||||
form: form,
|
||||
};
|
||||
});
|
||||
}, this, m[1])));
|
||||
}
|
||||
|
||||
return Promise.all(tasks).then(function(plugins) {
|
||||
var value = {};
|
||||
value[0] = data[0];
|
||||
value[1] = plugins;
|
||||
value[2] = mwan3Interfaces; // add mwan3 iface
|
||||
return value;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var m, s, o, triggers = [];
|
||||
var leds = data[0];
|
||||
var mwan3Interfaces = data[2]; // get ifaces from mwan3 config
|
||||
|
||||
for (var k in leds)
|
||||
for (var i = 0; i < leds[k].triggers.length; i++)
|
||||
triggers[i] = leds[k].triggers[i];
|
||||
|
||||
m = new form.Map('mwan3_led', _('MWAN3 Ledhelper'), _('Flash led on link state.'));
|
||||
s = m.section(form.GridSection, 'led', null);
|
||||
s.anonymous = false;
|
||||
s.addremove = true;
|
||||
|
||||
// filter NetworkSelect
|
||||
o = s.option(widgets.NetworkSelect, 'iface', _('Set interface'));
|
||||
o.exclude = s.section;
|
||||
o.nocreate = true;
|
||||
o.optional = true;
|
||||
// filter interfaces
|
||||
o.filter = function(section_id, value) {
|
||||
return mwan3Interfaces.indexOf(value) !== -1;
|
||||
};
|
||||
|
||||
o = s.option(form.ListValue, 'led_on', _('Select LED online'));
|
||||
Object.keys(leds).sort().forEach(function(name) {
|
||||
o.value(name);
|
||||
});
|
||||
o.value('', _('Exclude'));
|
||||
o.default = '';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.option(form.ListValue, 'led_off', _('Select LED offline'));
|
||||
Object.keys(leds).sort().forEach(function(name) {
|
||||
o.value(name);
|
||||
});
|
||||
o.value('', _('Exclude'));
|
||||
o.default = '';
|
||||
o.rmempty = true;
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
"Language: ru\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Last-Translator: Konstantine Shevlakov <shevlakov@132lan.ru>\n"
|
||||
|
||||
msgid "Flash led on link state."
|
||||
msgstr "Индикация светодиодов"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Имя"
|
||||
|
||||
msgid "Set interface"
|
||||
msgstr "Интерфейс"
|
||||
|
||||
msgid "Exclude"
|
||||
msgstr "Не использовать"
|
||||
|
||||
msgid "Select LED online"
|
||||
msgstr "LED \"в сети\""
|
||||
|
||||
msgid "Select LED offline"
|
||||
msgstr "LED \"вне сети\""
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"admin/network/mwan3/led": {
|
||||
"title": "LED",
|
||||
"order": 55,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/network/led"
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"luci-app-mwan3-ledhelper-nft": {
|
||||
"description": "Grant access to MWAN3 LED configuration",
|
||||
"read": {
|
||||
"file": {
|
||||
"/etc/init.d/mwan3": [ "exec" ],
|
||||
"/etc/config/mwan3": [ "read" ]
|
||||
},
|
||||
"cgi-io": [ "exec" ],
|
||||
"ubus": {
|
||||
"file": [ "exec" ],
|
||||
"uci": [ "changes", "get" ]
|
||||
},
|
||||
"uci": [ "mwan3_led" ]
|
||||
},
|
||||
"write": {
|
||||
"cgi-io": [ "exec" ],
|
||||
"ubus": {
|
||||
"file": [ "exec" ],
|
||||
"uci": [ "add", "apply", "confirm", "delete", "order", "rename", "set" ]
|
||||
},
|
||||
"uci": [ "mwan3_led" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# Copyright (C) 2017 Dan Luedtke <mail@danrl.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for the MWAN3 MultiWAN Manager
|
||||
LUCI_DEPENDS:=+luci-base +mwan3-nft
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -0,0 +1,8 @@
|
||||
#mwan3-service-status > .alert-message {
|
||||
display: inline-block;
|
||||
margin: 1rem;
|
||||
padding: 1rem;
|
||||
width: 15rem;
|
||||
height: 6rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
|
||||
render: function () {
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('mwan3', _('MultiWAN Manager - Globals'));
|
||||
|
||||
s = m.section(form.NamedSection, 'globals', 'globals');
|
||||
|
||||
o = s.option(form.Value, 'mmx_mask', _('Firewall mask'),
|
||||
_('Enter value in hex, starting with <code>0x</code>'));
|
||||
o.datatype = 'hex(4)';
|
||||
o.default = '0x3F00';
|
||||
|
||||
o = s.option(form.Flag, 'logging', _('Logging'),
|
||||
_('Enables global firewall logging'));
|
||||
|
||||
o = s.option(form.ListValue, 'loglevel', _('Loglevel'),
|
||||
_('Firewall loglevel'));
|
||||
o.default = 'notice';
|
||||
o.value('emerg', _('Emergency'));
|
||||
o.value('alert', _('Alert'));
|
||||
o.value('crit', _('Critical'));
|
||||
o.value('error', _('Error'));
|
||||
o.value('warning', _('Warning'));
|
||||
o.value('notice', _('Notice'));
|
||||
o.value('info', _('Info'));
|
||||
o.value('debug', _('Debug'));
|
||||
o.depends('logging', '1');
|
||||
|
||||
o = s.option(form.DynamicList, 'rt_table_lookup',
|
||||
_('Routing table lookup'),
|
||||
_('Also scan this Routing table for connected networks'));
|
||||
o.datatype = 'uinteger';
|
||||
o.value('220', _('Routing table %d').format('220'));
|
||||
|
||||
o = s.option(form.Flag, 'show_overview', _('Show on overview'),
|
||||
_('Show MultiWAN status section on the overview page'));
|
||||
o.default = o.enabled;
|
||||
o.rmempty = false;
|
||||
|
||||
return m.render();
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,324 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require view';
|
||||
'require uci';
|
||||
'require ui';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.stat('/usr/bin/httping'), {}),
|
||||
L.resolveDefault(fs.stat('/usr/bin/nping'), {}),
|
||||
L.resolveDefault(fs.stat('/usr/bin/arping'), {}),
|
||||
uci.load('network')
|
||||
]);
|
||||
},
|
||||
|
||||
render: function (stats) {
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('mwan3', _('MultiWAN Manager - Interfaces'),
|
||||
_('Mwan3 requires that all interfaces have a unique metric configured in /etc/config/network.') + '<br />' +
|
||||
_('Names must match the interface name found in /etc/config/network.') + '<br />' +
|
||||
_('Names may contain characters A-Z, a-z, 0-9, _ and no spaces-') + '<br />' +
|
||||
_('Interfaces may not share the same name as configured members, policies or rules.'));
|
||||
|
||||
s = m.section(form.GridSection, 'interface');
|
||||
s.addremove = true;
|
||||
s.anonymous = false;
|
||||
s.nodescriptions = true;
|
||||
|
||||
s.renderSectionAdd = function(extra_class) {
|
||||
var usedNames = [
|
||||
...uci.sections('mwan3', 'interface'),
|
||||
...uci.sections('mwan3', 'member'),
|
||||
...uci.sections('mwan3', 'policy'),
|
||||
...uci.sections('mwan3', 'rule')
|
||||
].map(function(sec) { return sec['.name']; });
|
||||
|
||||
var available = uci.sections('network', 'interface')
|
||||
.map(function(sec) { return sec['.name']; })
|
||||
.filter(function(name) {
|
||||
return name !== 'loopback' &&
|
||||
name.length <= 15 &&
|
||||
usedNames.indexOf(name) === -1;
|
||||
});
|
||||
|
||||
var el = E('div', { 'class': 'cbi-section-create' + (extra_class ? ' ' + extra_class : '') }, [
|
||||
E('div', { 'class': 'cbi-section-create-name-container' }, [
|
||||
E('select', {
|
||||
'class': 'cbi-section-create-name',
|
||||
'style': 'min-width: 12em'
|
||||
}, available.length
|
||||
? available.map(function(name) {
|
||||
return E('option', { 'value': name }, name);
|
||||
})
|
||||
: [E('option', { 'value': '', 'disabled': true, 'selected': true },
|
||||
_('No available interfaces'))]
|
||||
),
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-add',
|
||||
'title': _('Add'),
|
||||
'disabled': available.length === 0 || null,
|
||||
'click': ui.createHandlerFn(this, function(ev) {
|
||||
var select = ev.target.closest('.cbi-section-create')
|
||||
.querySelector('select.cbi-section-create-name');
|
||||
var name = select ? select.value : '';
|
||||
if (!name) return;
|
||||
return this.handleAdd(ev, name);
|
||||
})
|
||||
}, _('Add'))
|
||||
])
|
||||
]);
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enabled'));
|
||||
o.default = false;
|
||||
|
||||
o = s.option(form.ListValue, 'initial_state', _('Initial state'),
|
||||
_('Expect interface state on up event'));
|
||||
o.default = 'online';
|
||||
o.value('online', _('Online'));
|
||||
o.value('offline', _('Offline'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.ListValue, 'family', _('Internet Protocol'));
|
||||
o.default = 'ipv4';
|
||||
o.value('ipv4', _('IPv4'));
|
||||
o.value('ipv6', _('IPv6'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.DynamicList, 'track_ip', _('Tracking hostname or IP address'),
|
||||
_('This hostname or IP address will be pinged to determine if the link is up or down. Leave blank to assume interface is always online'));
|
||||
o.datatype = 'host';
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.ListValue, 'track_method', _('Tracking method'));
|
||||
o.default = 'ping';
|
||||
o.value('ping');
|
||||
if (stats[0].type === 'file') {
|
||||
o.value('httping');
|
||||
}
|
||||
if (stats[1].type === 'file') {
|
||||
o.value('nping-tcp');
|
||||
o.value('nping-udp');
|
||||
o.value('nping-icmp');
|
||||
o.value('nping-arp');
|
||||
}
|
||||
if (stats[2].type === 'file') {
|
||||
o.value('arping');
|
||||
}
|
||||
|
||||
o = s.option(form.Flag, 'httping_ssl', _('Enable ssl tracking'),
|
||||
_('Enables https tracking on ssl port 443'));
|
||||
o.depends('track_method', 'httping');
|
||||
o.rmempty = false;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'reliability', _('Tracking reliability'),
|
||||
_('Acceptable values: 1-100. This many Tracking IP addresses must respond for the link to be deemed up'));
|
||||
o.datatype = 'range(1, 100)';
|
||||
o.default = '1';
|
||||
|
||||
o = s.option(form.ListValue, 'count', _('Ping count'));
|
||||
o.default = '1';
|
||||
o.value('1');
|
||||
o.value('2');
|
||||
o.value('3');
|
||||
o.value('4');
|
||||
o.value('5');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'size', _('Ping size'));
|
||||
o.default = '56';
|
||||
o.depends('track_method', 'ping');
|
||||
o.value('8');
|
||||
o.value('24');
|
||||
o.value('56');
|
||||
o.value('120');
|
||||
o.value('248');
|
||||
o.value('504');
|
||||
o.value('1016');
|
||||
o.value('1472');
|
||||
o.value('2040');
|
||||
o.datatype = 'range(1, 65507)';
|
||||
o.modalonly = true;
|
||||
|
||||
o =s.option(form.Value, 'max_ttl', _('Max TTL'));
|
||||
o.default = '60';
|
||||
o.depends('track_method', 'ping');
|
||||
o.value('10');
|
||||
o.value('20');
|
||||
o.value('30');
|
||||
o.value('40');
|
||||
o.value('50');
|
||||
o.value('60');
|
||||
o.value('70');
|
||||
o.datatype = 'range(1, 255)';
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Flag, 'check_quality', _('Check link quality'));
|
||||
o.depends('track_method', 'ping');
|
||||
o.default = false;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'failure_latency', _('Failure latency [ms]'));
|
||||
o.depends('check_quality', '1');
|
||||
o.default = '1000';
|
||||
o.value('25');
|
||||
o.value('50');
|
||||
o.value('75');
|
||||
o.value('100');
|
||||
o.value('150');
|
||||
o.value('200');
|
||||
o.value('250');
|
||||
o.value('300');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'failure_loss', _('Failure packet loss [%]'));
|
||||
o.depends('check_quality', '1');
|
||||
o.default = '40';
|
||||
o.value('2');
|
||||
o.value('5');
|
||||
o.value('10');
|
||||
o.value('20');
|
||||
o.value('25');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'recovery_latency', _('Recovery latency [ms]'));
|
||||
o.depends('check_quality', '1');
|
||||
o.default = '500';
|
||||
o.value('25');
|
||||
o.value('50');
|
||||
o.value('75');
|
||||
o.value('100');
|
||||
o.value('150');
|
||||
o.value('200');
|
||||
o.value('250');
|
||||
o.value('300');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'recovery_loss', _('Recovery packet loss [%]'));
|
||||
o.depends('check_quality', '1');
|
||||
o.default = '10';
|
||||
o.value('2');
|
||||
o.value('5');
|
||||
o.value('10');
|
||||
o.value('20');
|
||||
o.value('25');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.ListValue, "timeout", _("Ping timeout"));
|
||||
o.default = '4';
|
||||
o.value('1', _('%d second').format('1'));
|
||||
for (var i = 2; i <= 10; i++)
|
||||
o.value(String(i), _('%d seconds').format(i));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.ListValue, 'interval', _('Ping interval'));
|
||||
o.default = '10';
|
||||
o.value('1', _('%d second').format('1'));
|
||||
o.value('3', _('%d seconds').format('3'));
|
||||
o.value('5', _('%d seconds').format('5'));
|
||||
o.value('10', _('%d seconds').format('10'));
|
||||
o.value('20', _('%d seconds').format('20'));
|
||||
o.value('30', _('%d seconds').format('30'));
|
||||
o.value('60', _('%d minute').format('1'));
|
||||
o.value('300', _('%d minutes').format('5'));
|
||||
o.value('600', _('%d minutes').format('10'));
|
||||
o.value('900', _('%d minutes').format('15'));
|
||||
o.value('1800', _('%d minutes').format('30'));
|
||||
o.value('3600', _('%d hour').format('1'));
|
||||
|
||||
o = s.option(form.Value, 'failure_interval', _('Failure interval'),
|
||||
_('Ping interval during failure detection'));
|
||||
o.default = '5';
|
||||
o.value('1', _('%d second').format('1'));
|
||||
o.value('3', _('%d seconds').format('3'));
|
||||
o.value('5', _('%d seconds').format('5'));
|
||||
o.value('10', _('%d seconds').format('10'));
|
||||
o.value('20', _('%d seconds').format('20'));
|
||||
o.value('30', _('%d seconds').format('30'));
|
||||
o.value('60', _('%d minute').format('1'));
|
||||
o.value('300', _('%d minutes').format('5'));
|
||||
o.value('600', _('%d minutes').format('10'));
|
||||
o.value('900', _('%d minutes').format('15'));
|
||||
o.value('1800', _('%d minutes').format('30'));
|
||||
o.value('3600', _('%d hour').format('1'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Flag, 'keep_failure_interval', _('Keep failure interval'),
|
||||
_('Keep ping failure interval during failure state'));
|
||||
o.default = false;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'recovery_interval', _('Recovery interval'),
|
||||
_('Ping interval during failure recovering'));
|
||||
o.default = '5';
|
||||
o.value('1', _('%d second').format('1'));
|
||||
o.value('3', _('%d seconds').format('3'));
|
||||
o.value('5', _('%d seconds').format('5'));
|
||||
o.value('10', _('%d seconds').format('10'));
|
||||
o.value('20', _('%d seconds').format('20'));
|
||||
o.value('30', _('%d seconds').format('30'));
|
||||
o.value('60', _('%d minute').format('1'));
|
||||
o.value('300', _('%d minutes').format('5'));
|
||||
o.value('600', _('%d minutes').format('10'));
|
||||
o.value('900', _('%d minutes').format('15'));
|
||||
o.value('1800', _('%d minutes').format('30'));
|
||||
o.value('3600', _('%d hour').format('1'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.ListValue, 'down', _('Interface down'),
|
||||
_('Interface will be deemed down after this many failed ping tests'));
|
||||
o.default = '5';
|
||||
o.value('1');
|
||||
o.value('2');
|
||||
o.value('3');
|
||||
o.value('4');
|
||||
o.value('5');
|
||||
o.value('6');
|
||||
o.value('7');
|
||||
o.value('8');
|
||||
o.value('9');
|
||||
o.value('10');
|
||||
|
||||
o = s.option(form.ListValue, 'up', _('Interface up'),
|
||||
_('Downed interface will be deemed up after this many successful ping tests'));
|
||||
o.default = "5";
|
||||
o.value('1');
|
||||
o.value('2');
|
||||
o.value('3');
|
||||
o.value('4');
|
||||
o.value('5');
|
||||
o.value('6');
|
||||
o.value('7');
|
||||
o.value('8');
|
||||
o.value('9');
|
||||
o.value('10');
|
||||
|
||||
o = s.option(form.DynamicList, 'flush_conntrack', _('Flush conntrack table'),
|
||||
_('Flush global firewall conntrack table on interface events'));
|
||||
o.value('ifup', _('ifup (netifd)'));
|
||||
o.value('ifdown', _('ifdown (netifd)'));
|
||||
o.value('connected', _('connected (mwan3)'));
|
||||
o.value('disconnected', _('disconnected (mwan3)'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.DummyValue, 'metric', _('Metric'),
|
||||
_('This displays the metric assigned to this interface in /etc/config/network'));
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = function(s) {
|
||||
var metric = uci.get('network', s, 'metric')
|
||||
if (metric)
|
||||
return metric;
|
||||
else
|
||||
return _('No interface metric set!');
|
||||
}
|
||||
|
||||
return m.render();
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,67 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require view';
|
||||
'require uci';
|
||||
'require ui';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
uci.load('mwan3')
|
||||
]);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('mwan3', _('MultiWAN Manager - Members'),
|
||||
_('Members are profiles attaching a metric and weight to an MWAN interface.') + '<br />' +
|
||||
_('Names may contain characters A-Z, a-z, 0-9, _ and no spaces.') + '<br />' +
|
||||
_('Members may not share the same name as configured interfaces, policies or rules.'));
|
||||
|
||||
s = m.section(form.GridSection, 'member');
|
||||
s.addremove = true;
|
||||
s.anonymous = false;
|
||||
s.nodescriptions = true;
|
||||
|
||||
/* This name length error check can likely be removed when mwan3 migrates to nftables */
|
||||
s.renderSectionAdd = function(extra_class) {
|
||||
var el = form.GridSection.prototype.renderSectionAdd.apply(this, arguments),
|
||||
nameEl = el.querySelector('.cbi-section-create-name');
|
||||
ui.addValidator(nameEl, 'uciname', true, function(v) {
|
||||
let sections = [
|
||||
...uci.sections('mwan3', 'interface'),
|
||||
...uci.sections('mwan3', 'member'),
|
||||
...uci.sections('mwan3', 'policy'),
|
||||
...uci.sections('mwan3', 'rule')
|
||||
];
|
||||
|
||||
for (let j = 0; j < sections.length; j++) {
|
||||
if (sections[j]['.name'] == v) {
|
||||
return _('Members may not share the same name as configured interfaces, policies or rules.');
|
||||
}
|
||||
}
|
||||
if (v.length > 15) return _('Name length shall not exceed 15 characters');
|
||||
return true;
|
||||
}, 'blur', 'keyup');
|
||||
return el;
|
||||
};
|
||||
|
||||
o = s.option(form.ListValue, 'interface', _('Interface'));
|
||||
var options = uci.sections('mwan3', 'interface')
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var value = options[i]['.name'];
|
||||
o.value(value);
|
||||
}
|
||||
|
||||
o = s.option(form.Value, 'metric', _('Metric'),
|
||||
_('Acceptable values: 1-256. Defaults to 1 if not set'));
|
||||
o.datatype = 'range(1, 256)';
|
||||
|
||||
o = s.option(form.Value, 'weight', _('Weight'),
|
||||
_('Acceptable values: 1-1000. Defaults to 1 if not set'));
|
||||
o.datatype = 'range(1, 1000)';
|
||||
|
||||
return m.render();
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require fs';
|
||||
'require ui';
|
||||
|
||||
const isReadonlyView = !L.hasViewPermission() || null;
|
||||
|
||||
return view.extend({
|
||||
load() {
|
||||
return L.resolveDefault(fs.read('/etc/mwan3.user'), '');
|
||||
},
|
||||
|
||||
handleSave(ev) {
|
||||
const value = (document.querySelector('textarea').value || '').trim().replace(/\r\n/g, '\n') + '\n';
|
||||
|
||||
return fs.write('/etc/mwan3.user', value).then(function(rc) {
|
||||
document.querySelector('textarea').value = value;
|
||||
ui.addNotification(null, E('p', _('Contents have been saved.')), 'info');
|
||||
}).catch(function(e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
|
||||
});
|
||||
},
|
||||
|
||||
render(mwan3user) {
|
||||
return E([
|
||||
E('h2', _('MultiWAN Manager - Notify')),
|
||||
E('p', { 'class': 'cbi-section-descr' },
|
||||
_('This section allows you to modify the content of "/etc/mwan3.user".') + '<br/>' +
|
||||
_('The file is also preserved during sysupgrade.') + '<br/>' +
|
||||
'<br />' +
|
||||
_('Notes:') + '<br />' +
|
||||
_('This file is interpreted as a shell script.') + '<br />' +
|
||||
_('The first line of the script must be "#!/bin/sh" without quotes.') + '<br />' +
|
||||
_('Lines beginning with # are comments and are not executed.') + '<br />' +
|
||||
_('Put your custom mwan3 action here, they will be executed with each netifd hotplug interface event on interfaces for which mwan3 is enabled.') + '<br />' +
|
||||
'<br />' +
|
||||
_('There are three main environment variables that are passed to this script.') + '<br />' +
|
||||
'<br />' +
|
||||
_('%s: Name of the action that triggered this event').format('$ACTION') + '<br />' +
|
||||
_('* %s: Is called by netifd and mwan3track').format('ifup') + '<br />' +
|
||||
_('* %s: Is called by netifd and mwan3track').format('ifdown') + '<br />' +
|
||||
_('* %s: Is only called by mwan3track if tracking was successful').format('connected') + '<br />' +
|
||||
_('* %s: Is only called by mwan3track if tracking has failed').format('disonnected') + '<br />' +
|
||||
_('%s: Name of the interface which went up or down (e.g. "wan" or "wwan")').format('$INTERFACE') + '<br />' +
|
||||
_('%s: Name of Physical device which interface went up or down (e.g. "eth0" or "wwan0")').format('$DEVICE') + '<br />'),
|
||||
E('p', {}, E('textarea', { 'style': 'width:100%', 'rows': 10, 'disabled': isReadonlyView }, [ mwan3user != null ? mwan3user : '' ]))
|
||||
]);
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleReset: null
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require view';
|
||||
'require uci';
|
||||
'require ui';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
uci.load('mwan3')
|
||||
]);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('mwan3', _('MultiWAN Manager - Policies'),
|
||||
_('Policies are profiles grouping one or more members controlling how Mwan3 distributes traffic.') + '<br />' +
|
||||
_('Member interfaces with lower metrics are used first.') + '<br />' +
|
||||
_('Member interfaces with the same metric will be load-balanced.') + '<br />' +
|
||||
_('Load-balanced member interfaces distribute more traffic out those with higher weights.') + '<br />' +
|
||||
_('Names may contain characters A-Z, a-z, 0-9, _ and no spaces.') + '<br />' +
|
||||
_('Names must be 15 characters or less.') + '<br />' +
|
||||
_('Policies may not share the same name as configured interfaces, members or rules'));
|
||||
|
||||
s = m.section(form.GridSection, 'policy');
|
||||
s.addremove = true;
|
||||
s.anonymous = false;
|
||||
s.nodescriptions = true;
|
||||
|
||||
/* This name length error check can likely be removed when mwan3 migrates to nftables */
|
||||
s.renderSectionAdd = function(extra_class) {
|
||||
var el = form.GridSection.prototype.renderSectionAdd.apply(this, arguments),
|
||||
nameEl = el.querySelector('.cbi-section-create-name');
|
||||
ui.addValidator(nameEl, 'uciname', true, function(v) {
|
||||
let sections = [
|
||||
...uci.sections('mwan3', 'interface'),
|
||||
...uci.sections('mwan3', 'member'),
|
||||
...uci.sections('mwan3', 'policy'),
|
||||
...uci.sections('mwan3', 'rule')
|
||||
];
|
||||
|
||||
for (let j = 0; j < sections.length; j++) {
|
||||
if (sections[j]['.name'] == v) {
|
||||
return _('Policies may not share the same name as configured interfaces, members or rules');
|
||||
}
|
||||
}
|
||||
if (v.length > 15) return _('Name length shall not exceed 15 characters');
|
||||
return true;
|
||||
}, 'blur', 'keyup');
|
||||
return el;
|
||||
};
|
||||
|
||||
o = s.option(form.DynamicList, 'use_member', _('Member used'));
|
||||
var options = uci.sections('mwan3', 'member')
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var value = options[i]['.name'];
|
||||
o.value(value);
|
||||
}
|
||||
|
||||
o = s.option(form.ListValue, 'last_resort', _('Last resort'),
|
||||
_('When all policy members are offline use this behavior for matched traffic'));
|
||||
o.default = 'unreachable';
|
||||
o.value('unreachable', _('unreachable (reject)'));
|
||||
o.value('blackhole', _('blackhole (drop)'));
|
||||
o.value('default', _('default (use main routing table)'));
|
||||
|
||||
return m.render();
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,132 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require view';
|
||||
'require uci';
|
||||
'require ui';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
fs.exec_direct('/usr/libexec/luci-mwan3', ['ipset', 'dump']),
|
||||
uci.load('mwan3')
|
||||
]);
|
||||
},
|
||||
|
||||
render: function (data) {
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('mwan3', _('MultiWAN Manager - Rules'),
|
||||
_('Rules specify which traffic will use a particular MWAN policy.') + '<br />' +
|
||||
_('Rules are based on IP address, port or protocol.') + '<br />' +
|
||||
_('Rules are matched from top to bottom.') + '<br />' +
|
||||
_('Rules below a matching rule are ignored.') + '<br />' +
|
||||
_('Traffic not matching any rule is routed using the main routing table.') + '<br />' +
|
||||
_('Traffic destined for known (other than default) networks is handled by the main routing table.') + '<br />' +
|
||||
_('Traffic matching a rule, but all WAN interfaces for that policy are down will be blackholed.') + '<br />' +
|
||||
_('Names may contain characters A-Z, a-z, 0-9, _ and no spaces.') + '<br />' +
|
||||
_('Rules may not share the same name as configured interfaces, members or policies.'));
|
||||
|
||||
s = m.section(form.GridSection, 'rule');
|
||||
s.addremove = true;
|
||||
s.anonymous = false;
|
||||
s.nodescriptions = true;
|
||||
s.sortable = true;
|
||||
|
||||
/* This name length error check can likely be removed when mwan3 migrates to nftables */
|
||||
s.renderSectionAdd = function(extra_class) {
|
||||
const el = form.GridSection.prototype.renderSectionAdd.apply(this, arguments);
|
||||
const nameEl = el.querySelector('.cbi-section-create-name');
|
||||
ui.addValidator(nameEl, 'uciname', true, function(v) {
|
||||
let sections = [
|
||||
...uci.sections('mwan3', 'interface'),
|
||||
...uci.sections('mwan3', 'member'),
|
||||
...uci.sections('mwan3', 'policy'),
|
||||
...uci.sections('mwan3', 'rule')
|
||||
];
|
||||
|
||||
for (let j = 0; j < sections.length; j++) {
|
||||
if (sections[j]['.name'] == v) {
|
||||
return _('Rules may not share the same name as configured interfaces, members or policies.');
|
||||
}
|
||||
}
|
||||
if (v.length > 15) return _('Name length shall not exceed 15 characters');
|
||||
return true;
|
||||
}, 'blur', 'keyup');
|
||||
return el;
|
||||
};
|
||||
|
||||
o = s.option(form.ListValue, 'family', _('Internet Protocol'));
|
||||
o.default = '';
|
||||
o.value('', _('IPv4 and IPv6'));
|
||||
o.value('ipv4', _('IPv4 only'));
|
||||
o.value('ipv6', _('IPv6 only'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'proto', _('Protocol'),
|
||||
_('View the content of /etc/protocols for protocol description'));
|
||||
o.default = 'all';
|
||||
o.rmempty = false;
|
||||
o.value('all');
|
||||
o.value('tcp');
|
||||
o.value('udp');
|
||||
o.value('icmp');
|
||||
o.value('esp');
|
||||
|
||||
o = s.option(form.Value, 'src_ip', _('Source address'),
|
||||
_('Supports CIDR notation (eg "192.168.100.0/24") without quotes'));
|
||||
o.datatype = 'ipaddr';
|
||||
|
||||
o = s.option(form.Value, 'src_port', _('Source port'),
|
||||
_('May be entered as a single or multiple port(s) (eg "22" or "80,443") or as a portrange (eg "1024:2048") without quotes'));
|
||||
o.depends('proto', 'tcp');
|
||||
o.depends('proto', 'udp');
|
||||
|
||||
o = s.option(form.Value, 'dest_ip', _('Destination address'),
|
||||
_('Supports CIDR notation (eg "192.168.100.0/24") without quotes'));
|
||||
o.datatype = 'ipaddr';
|
||||
|
||||
o = s.option(form.Value, 'dest_port', _('Destination port'),
|
||||
_('May be entered as a single or multiple port(s) (eg "22" or "80,443") or as a portrange (eg "1024:2048") without quotes'));
|
||||
o.depends('proto', 'tcp');
|
||||
o.depends('proto', 'udp');
|
||||
|
||||
o = s.option(form.ListValue, 'sticky', _('Sticky'),
|
||||
_('Traffic from the same source IP address that previously matched this rule within the sticky timeout period will use the same WAN interface'));
|
||||
o.default = '0';
|
||||
o.value('1', _('Yes'));
|
||||
o.value('0', _('No'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Value, 'timeout', _('Sticky timeout'),
|
||||
_('Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set'));
|
||||
o.datatype = 'range(1, 1000000)';
|
||||
o.modalonly = true;
|
||||
o.depends('sticky', '1');
|
||||
|
||||
o = s.option(form.Value, 'ipset', _('IPset'),
|
||||
_('Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg "ipset=/youtube.com/youtube")'));
|
||||
o.value('', _('-- Please choose --'));
|
||||
let ipsets = data[0].split(/\n/);
|
||||
for (let ips of ipsets) {
|
||||
if (ips.length > 0)
|
||||
o.value(ips);
|
||||
}
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.Flag, 'logging', _('Logging'),
|
||||
_('Enables firewall rule logging (global mwan3 logging must also be enabled)'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.option(form.ListValue, 'use_policy', _('Policy assigned'));
|
||||
let options = uci.sections('mwan3', 'policy')
|
||||
for (let opt of options) {
|
||||
o.value(opt['.name']);
|
||||
}
|
||||
o.value('unreachable', _('unreachable (reject)'));
|
||||
o.value('blackhole', _('blackhole (drop)'));
|
||||
o.value('default', _('default (use main routing table)'));
|
||||
|
||||
return m.render();
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
'require fs';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return L.resolveDefault(fs.exec_direct('/usr/sbin/mwan3', [ 'status' ]),'');
|
||||
},
|
||||
|
||||
render: function (report) {
|
||||
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
|
||||
E('h2', _('MultiWAN Manager - Status')),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('pre', [ report ])
|
||||
]),
|
||||
])
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
})
|
||||
@@ -0,0 +1,116 @@
|
||||
'use strict';
|
||||
'require fs';
|
||||
'require uci';
|
||||
'require dom';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
handleCommand: function(exec, args) {
|
||||
var buttons = document.querySelectorAll('.cbi-button');
|
||||
|
||||
for (var i = 0; i < buttons.length; i++)
|
||||
buttons[i].setAttribute('disabled', 'true');
|
||||
|
||||
return fs.exec(exec, args).then(function(res) {
|
||||
var out = document.querySelector('.command-output');
|
||||
out.style.display = '';
|
||||
|
||||
dom.content(out, [ res.stdout || '', res.stderr || '' ]);
|
||||
}).catch(function(err) {
|
||||
ui.addNotification(null, E('p', [ err ]))
|
||||
}).finally(function() {
|
||||
for (var i = 0; i < buttons.length; i++)
|
||||
buttons[i].removeAttribute('disabled');
|
||||
});
|
||||
},
|
||||
|
||||
handleAction: function(ev) {
|
||||
var iface = document.getElementById('iface');
|
||||
var task = document.getElementById('task');
|
||||
|
||||
switch (task.value) {
|
||||
case 'gateway':
|
||||
return this.handleCommand('/usr/libexec/luci-mwan3',
|
||||
[ 'diag', 'gateway', iface.value ]);
|
||||
case 'tracking':
|
||||
return this.handleCommand('/usr/libexec/luci-mwan3',
|
||||
[ 'diag', 'tracking', iface.value ]);
|
||||
case 'rules':
|
||||
return this.handleCommand('/usr/libexec/luci-mwan3',
|
||||
[ 'diag', 'rules', iface.value ]);
|
||||
case 'routes':
|
||||
return this.handleCommand('/usr/libexec/luci-mwan3',
|
||||
[ 'diag', 'routes', iface.value ]);
|
||||
case 'ifup':
|
||||
return this.handleCommand('/usr/sbin/mwan3',
|
||||
[ 'ifup', iface.value]);
|
||||
case 'ifdown':
|
||||
return this.handleCommand('/usr/sbin/mwan3',
|
||||
[ 'ifdown', iface.value]);
|
||||
}
|
||||
},
|
||||
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
uci.load('mwan3')
|
||||
]);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
|
||||
var taskSel = [
|
||||
E('option', { 'value': 'gateway' }, [ _('Ping default gateway') ]),
|
||||
E('option', { 'value': 'tracking' }, [ _('Ping tracking IP') ]),
|
||||
E('option', { 'value': 'rules' }, [ _('Check IP rules') ]),
|
||||
E('option', { 'value': 'routes' }, [ _('Check routing table') ]),
|
||||
E('option', { 'value': 'ifup' }, [ _('Hotplug ifup') ]),
|
||||
E('option', { 'value': 'ifdown' }, [ _('Hotplug ifdown') ])
|
||||
];
|
||||
|
||||
var ifaceSel = [E('option', { value: '' }, [_('-- Interface Selection --')])];
|
||||
|
||||
var options = uci.sections('mwan3', 'interface')
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
ifaceSel.push(E('option', { 'value': options[i]['.name'] }, options[i]['.name']));
|
||||
}
|
||||
|
||||
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
|
||||
E('h2', {}, [ _('MultiWAN Manager - Diagnostics') ]),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'cbi-section-node' }, [
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, [ _('Interface') ]),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('select', {'class': 'cbi-input-select', 'id': 'iface'},
|
||||
ifaceSel
|
||||
)
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, [ _('Task') ]),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('select', { 'class': 'cbi-input-select', 'id': 'task' },
|
||||
taskSel
|
||||
)
|
||||
])
|
||||
])
|
||||
])
|
||||
]),
|
||||
'\xa0',
|
||||
E('pre', { 'class': 'command-output', 'style': 'display:none' }),
|
||||
'\xa0',
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'id': 'execute',
|
||||
'click': ui.createHandlerFn(this, 'handleAction')
|
||||
}, [ _('Execute') ]),
|
||||
]),
|
||||
]);
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
})
|
||||
@@ -0,0 +1,109 @@
|
||||
'use strict';
|
||||
'require poll';
|
||||
'require view';
|
||||
'require rpc';
|
||||
|
||||
const callMwan3Status = rpc.declare({
|
||||
object: 'mwan3',
|
||||
method: 'status',
|
||||
params: ['section'],
|
||||
expect: { },
|
||||
});
|
||||
|
||||
function getStatusBackgroundClass(status) {
|
||||
switch (status) {
|
||||
case 'online':
|
||||
return 'label success';
|
||||
case 'offline':
|
||||
return 'label warning';
|
||||
case 'disabled':
|
||||
return 'label';
|
||||
case 'notracking':
|
||||
return 'label';
|
||||
default:
|
||||
return 'label';
|
||||
}
|
||||
}
|
||||
|
||||
function renderMwan3Status(status) {
|
||||
if (!status.interfaces)
|
||||
return '<strong>%h</strong>'.format(_('No MWAN interfaces found'));
|
||||
|
||||
var tableHtml = '<table class="table cbi-section-table" style="width: 100%;">';
|
||||
tableHtml += '<thead><tr class="tr cbi-section-table-titles">';
|
||||
tableHtml += '<th class="th left">' + _('Interface') + '</th>';
|
||||
tableHtml += '<th class="th left">' + _('Status') + '</th>';
|
||||
tableHtml += '<th class="th left">' + _('Uptime') + '</th>';
|
||||
tableHtml += '</tr></thead><tbody>';
|
||||
|
||||
for (var iface in status.interfaces) {
|
||||
var state = '';
|
||||
var time = '';
|
||||
var statusType = status.interfaces[iface].status;
|
||||
|
||||
switch (statusType) {
|
||||
case 'online':
|
||||
state = _('Online');
|
||||
time = '%t'.format(status.interfaces[iface].online);
|
||||
break;
|
||||
case 'offline':
|
||||
state = _('Offline');
|
||||
time = '%t'.format(status.interfaces[iface].offline);
|
||||
break;
|
||||
case 'notracking':
|
||||
state = _('No Tracking');
|
||||
if ((status.interfaces[iface].uptime) > 0) {
|
||||
time = '%t'.format(status.interfaces[iface].uptime);
|
||||
} else {
|
||||
time = '';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
state = _('Disabled');
|
||||
time = '';
|
||||
break;
|
||||
}
|
||||
|
||||
var statusClass = getStatusBackgroundClass(statusType);
|
||||
|
||||
tableHtml += '<tr class="tr cbi-section-table-row">';
|
||||
tableHtml += '<td class="td left"><strong>' + iface + '</strong></td>';
|
||||
tableHtml += '<td class="td left"><span class="' + statusClass + '">' + state + '</span></td>';
|
||||
tableHtml += '<td class="td left">' + (time || '') + '</td>';
|
||||
tableHtml += '</tr>';
|
||||
}
|
||||
|
||||
tableHtml += '</tbody></table>';
|
||||
|
||||
return tableHtml;
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
callMwan3Status("interfaces"),
|
||||
]);
|
||||
},
|
||||
|
||||
render: function (data) {
|
||||
poll.add(function() {
|
||||
return callMwan3Status("interfaces").then(function(result) {
|
||||
var view = document.getElementById('mwan3-service-status');
|
||||
view.innerHTML = renderMwan3Status(result);
|
||||
});
|
||||
});
|
||||
|
||||
return E('div', { class: 'cbi-map' }, [
|
||||
E('h2', [ _('MultiWAN Manager - Overview') ]),
|
||||
E('div', { class: 'cbi-section' }, [
|
||||
E('div', { 'id': 'mwan3-service-status' }, [
|
||||
E('em', { 'class': 'spinning' }, [ _('Collecting data ...') ])
|
||||
])
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
'require fs';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return L.resolveDefault(fs.exec_direct('/usr/sbin/mwan3', [ 'internal', 'ipv4' ]),'');
|
||||
},
|
||||
|
||||
render: function (report) {
|
||||
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
|
||||
E('h2', _('MultiWAN Manager - Troubleshooting')),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('pre', [ report ])
|
||||
]),
|
||||
])
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
})
|
||||
@@ -0,0 +1,117 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
|
||||
const callMwan3Status = rpc.declare({
|
||||
object: 'mwan3',
|
||||
method: 'status',
|
||||
params: ['section'],
|
||||
expect: { },
|
||||
});
|
||||
|
||||
function getStatusBackgroundClass(status) {
|
||||
switch (status) {
|
||||
case 'online':
|
||||
return 'label success';
|
||||
case 'offline':
|
||||
return 'label warning';
|
||||
case 'disabled':
|
||||
return 'label';
|
||||
case 'notracking':
|
||||
return 'label';
|
||||
default:
|
||||
return 'label';
|
||||
}
|
||||
}
|
||||
|
||||
return baseclass.extend({
|
||||
title: _('MultiWAN Manager'),
|
||||
|
||||
load: function() {
|
||||
return uci.load('mwan3').then(function() {
|
||||
var globals = uci.sections('mwan3', 'globals');
|
||||
if (!globals || !globals[0] || globals[0].show_overview !== '1')
|
||||
return null;
|
||||
return Promise.all([
|
||||
callMwan3Status("interfaces"),
|
||||
]);
|
||||
});
|
||||
},
|
||||
|
||||
render: function (result) {
|
||||
if (!result)
|
||||
return null;
|
||||
|
||||
if (!result[0]?.interfaces || Object.keys(result[0].interfaces).length === 0)
|
||||
return null;
|
||||
|
||||
// Основной контейнер
|
||||
var container = E('div', { 'class': 'cbi-section' });
|
||||
|
||||
// Таблица с системными классами LuCI
|
||||
var table = E('table', { 'class': 'table cbi-section-table' });
|
||||
|
||||
// Заголовок
|
||||
var thead = E('tr', { 'class': 'tr cbi-section-table-titles' });
|
||||
thead.appendChild(E('th', { 'class': 'th left' }, [ _('Interface') ]));
|
||||
thead.appendChild(E('th', { 'class': 'th left' }, [ _('Status') ]));
|
||||
thead.appendChild(E('th', { 'class': 'th left' }, [ _('Uptime') ]));
|
||||
table.appendChild(thead);
|
||||
|
||||
// Тело таблицы
|
||||
var tbody = E('tbody');
|
||||
|
||||
for (var iface in result[0].interfaces) {
|
||||
var state = '';
|
||||
var time = '';
|
||||
var statusType = result[0].interfaces[iface].status;
|
||||
|
||||
switch (statusType) {
|
||||
case 'online':
|
||||
state = _('Online');
|
||||
time = '%t'.format(result[0].interfaces[iface].online);
|
||||
break;
|
||||
case 'offline':
|
||||
state = _('Offline');
|
||||
time = '%t'.format(result[0].interfaces[iface].offline);
|
||||
break;
|
||||
case 'notracking':
|
||||
state = _('No Tracking');
|
||||
if ((result[0].interfaces[iface].uptime) > 0) {
|
||||
time = '%t'.format(result[0].interfaces[iface].uptime);
|
||||
} else {
|
||||
time = '';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
state = _('Disabled');
|
||||
time = '';
|
||||
break;
|
||||
}
|
||||
|
||||
var tr = E('tr', { 'class': 'tr cbi-section-table-row' });
|
||||
|
||||
// Ячейка интерфейса
|
||||
tr.appendChild(E('td', { 'class': 'td left' }, [
|
||||
E('strong', {}, [ iface ])
|
||||
]));
|
||||
|
||||
// Ячейка статуса с цветным фоном через системные классы label
|
||||
var statusClass = getStatusBackgroundClass(statusType);
|
||||
tr.appendChild(E('td', { 'class': 'td left' }, [
|
||||
E('span', { 'class': statusClass }, [ state ])
|
||||
]));
|
||||
|
||||
// Ячейка времени
|
||||
tr.appendChild(E('td', { 'class': 'td left' }, [ time || '' ]));
|
||||
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
|
||||
table.appendChild(tbody);
|
||||
container.appendChild(table);
|
||||
|
||||
return container;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,886 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: LuCI: mwan3\n"
|
||||
"POT-Creation-Date: 2017-09-14 16:00+0300\n"
|
||||
"PO-Revision-Date: 2026-05-02 12:03+0000\n"
|
||||
"Last-Translator: SnIPeRSnIPeR "
|
||||
"<snipersniper@users.noreply.hosted.weblate.org>\n"
|
||||
"Language-Team: Russian <https://hosted.weblate.org/projects/openwrt/"
|
||||
"luciapplicationsmwan3/ru/>\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Weblate 5.17.1\n"
|
||||
"Project-Info: Это технический перевод, не дословный. Главное-удобный русский "
|
||||
"интерфейс, все проверялось в графическом режиме, совместим с другими apps\n"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:211
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:227
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:249
|
||||
msgid "%d hour"
|
||||
msgstr "%d час"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:206
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:222
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:244
|
||||
msgid "%d minute"
|
||||
msgstr "%d минута"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:207
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:208
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:209
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:210
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:223
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:224
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:225
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:226
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:245
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:246
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:247
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:248
|
||||
msgid "%d minutes"
|
||||
msgstr "%d минут"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:193
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:200
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:216
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:238
|
||||
msgid "%d second"
|
||||
msgstr "%d секунда"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:195
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:201
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:202
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:203
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:204
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:205
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:217
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:218
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:219
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:220
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:221
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:239
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:240
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:241
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:242
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:243
|
||||
msgid "%d seconds"
|
||||
msgstr "%d секунд"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:45
|
||||
msgid ""
|
||||
"%s: Name of Physical device which interface went up or down (e.g. \"eth0\" "
|
||||
"or \"wwan0\")"
|
||||
msgstr ""
|
||||
"%s: Название физического устройства, интерфейс которого поднялся или упал "
|
||||
"(прим. \"eth0\" или \"wwan0\")"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:39
|
||||
msgid "%s: Name of the action that triggered this event"
|
||||
msgstr "%s: Название действия вызвавшего это событие"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:44
|
||||
msgid ""
|
||||
"%s: Name of the interface which went up or down (e.g. \"wan\" or \"wwan\")"
|
||||
msgstr ""
|
||||
"%s: Название интерфейса который поднялся или упал (прим. \"wan\" или "
|
||||
"\"wwan\")"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:40
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:41
|
||||
msgid "* %s: Is called by netifd and mwan3track"
|
||||
msgstr "* %s: Вызывается netifd и mwan3track"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:43
|
||||
msgid "* %s: Is only called by mwan3track if tracking has failed"
|
||||
msgstr ""
|
||||
"* %s: Вызывается mwan3track только в том случае, если отслеживание не удалось"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:42
|
||||
msgid "* %s: Is only called by mwan3track if tracking was successful"
|
||||
msgstr "* %s: Вызывается mwan3track только в случае успешного отслеживания"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:71
|
||||
msgid "-- Interface Selection --"
|
||||
msgstr "-- Выбор интерфейса --"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:109
|
||||
msgid "-- Please choose --"
|
||||
msgstr "-- Выберите --"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:99
|
||||
msgid ""
|
||||
"Acceptable values: 1-100. This many Tracking IP addresses must respond for "
|
||||
"the link to be deemed up"
|
||||
msgstr ""
|
||||
"Допустимые значения: 1–100. Количество IP-адресов, которое должно ответить "
|
||||
"чтобы соединение было признано активным"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:62
|
||||
msgid "Acceptable values: 1-1000. Defaults to 1 if not set"
|
||||
msgstr "Допустимые значения: 1–1000. По умолчанию 1, если значение не задано"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:58
|
||||
msgid "Acceptable values: 1-256. Defaults to 1 if not set"
|
||||
msgstr "Допустимые значения: 1–256 По умолчанию 1, если значение не задано"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:26
|
||||
msgid "Alert"
|
||||
msgstr "Тревога"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:37
|
||||
msgid "Also scan this Routing table for connected networks"
|
||||
msgstr ""
|
||||
"Также сканировать эту таблицу маршрутизации на предмет подключённых сетей"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:65
|
||||
msgid "Check IP rules"
|
||||
msgstr "Проверить правила IP"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:140
|
||||
msgid "Check link quality"
|
||||
msgstr "Проверка качества подключения"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:66
|
||||
msgid "Check routing table"
|
||||
msgstr "Проверить таблицу маршрутизации"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:96
|
||||
msgid "Collecting data ..."
|
||||
msgstr "Сбор данных ..."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:18
|
||||
msgid "Contents have been saved."
|
||||
msgstr "Содержимое сохранено."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:27
|
||||
msgid "Critical"
|
||||
msgstr "Критический"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:32
|
||||
msgid "Debug"
|
||||
msgstr "Отладка"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:85
|
||||
msgid "Destination address"
|
||||
msgstr "Адрес назначения"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:89
|
||||
msgid "Destination port"
|
||||
msgstr "Порт назначения"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:31
|
||||
msgid "Diagnostics"
|
||||
msgstr "Диагностика"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:57
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:66
|
||||
msgid "Disabled"
|
||||
msgstr "Отключено"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:267
|
||||
msgid ""
|
||||
"Downed interface will be deemed up after this many successful ping tests"
|
||||
msgstr ""
|
||||
"Отключённый интерфейс будет считаться активным после указанного количество "
|
||||
"успешных ping проверок"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:41
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:49
|
||||
msgid "Downtime"
|
||||
msgstr "Время простоя"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:25
|
||||
msgid "Emergency"
|
||||
msgstr "Аварийный"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:92
|
||||
msgid "Enable ssl tracking"
|
||||
msgstr "Включить отслеживание SSL"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:55
|
||||
msgid "Enabled"
|
||||
msgstr "Включено"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:118
|
||||
msgid ""
|
||||
"Enables firewall rule logging (global mwan3 logging must also be enabled)"
|
||||
msgstr ""
|
||||
"Включает журналирование правил брандмауэра (также должно быть включено "
|
||||
"глобальное журналирование mwan3)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:20
|
||||
msgid "Enables global firewall logging"
|
||||
msgstr "Включает глобальное журналирование правил брандмауэера"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:93
|
||||
msgid "Enables https tracking on ssl port 443"
|
||||
msgstr "Включает отслеживание HTTPS на SSL порту 443"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:15
|
||||
msgid "Enter value in hex, starting with <code>0x</code>"
|
||||
msgstr "Введите значение в шестнадцатеричной форме, начиная с <code>0x</code>"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:28
|
||||
msgid "Error"
|
||||
msgstr "Ошибка"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:108
|
||||
msgid "Execute"
|
||||
msgstr "Выполнить"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:59
|
||||
msgid "Expect interface state on up event"
|
||||
msgstr "Ожидать состояние интерфейса при событии подключения интерейса"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:213
|
||||
msgid "Failure interval"
|
||||
msgstr "Интервал отказа"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:145
|
||||
msgid "Failure latency [ms]"
|
||||
msgstr "Задержка при отказе [мс]"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:158
|
||||
msgid "Failure packet loss [%]"
|
||||
msgstr "Потери пакетов при отказе [%]"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:23
|
||||
msgid "Firewall loglevel"
|
||||
msgstr "Уровень журналирования брандмауэра"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:14
|
||||
msgid "Firewall mask"
|
||||
msgstr "Маска межсетевого экрана"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:280
|
||||
msgid "Flush conntrack table"
|
||||
msgstr "Сбрасывать conntrack таблицу"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:281
|
||||
msgid "Flush global firewall conntrack table on interface events"
|
||||
msgstr ""
|
||||
"Сбрасывать глобальную таблицу conntrack межсетевого экрана при событиях "
|
||||
"интерфейса"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:59
|
||||
msgid "Globals"
|
||||
msgstr "Глобальные"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/rpcd/acl.d/luci-app-mwan3.json:51
|
||||
msgid "Grant access for luci-app-mwan3 configuration"
|
||||
msgstr "Предоставить доступ для настройки luci-app-mwan3"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/rpcd/acl.d/luci-app-mwan3.json:3
|
||||
msgid "Grant access for luci-app-mwan3 status information"
|
||||
msgstr "Предоставить доступ к информации о состоянии luci-app-mwan3"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:68
|
||||
msgid "Hotplug ifdown"
|
||||
msgstr "Hotplug ifdown"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:67
|
||||
msgid "Hotplug ifup"
|
||||
msgstr "Hotplug ifup"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:107
|
||||
msgid "IPset"
|
||||
msgstr "IPset"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:67
|
||||
msgid "IPv4"
|
||||
msgstr "IPv4"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:61
|
||||
msgid "IPv4 and IPv6"
|
||||
msgstr "IPv4 и IPv6"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:62
|
||||
msgid "IPv4 only"
|
||||
msgstr "Только IPv4"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:68
|
||||
msgid "IPv6"
|
||||
msgstr "IPv6"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:63
|
||||
msgid "IPv6 only"
|
||||
msgstr "Только IPv6"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:31
|
||||
msgid "Info"
|
||||
msgstr "Информация"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:58
|
||||
msgid "Initial state"
|
||||
msgstr "Исходное состояние"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:50
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:83
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:65
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:77
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:101
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:67
|
||||
msgid "Interface"
|
||||
msgstr "Интерфейс"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:252
|
||||
msgid "Interface down"
|
||||
msgstr "Отключение интерфейса"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:266
|
||||
msgid "Interface up"
|
||||
msgstr "Включение интерфейса"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:253
|
||||
msgid "Interface will be deemed down after this many failed ping tests"
|
||||
msgstr ""
|
||||
"Интерфейс будет считаться неработающим после заданного количество неудачных "
|
||||
"пинг-запросов"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:25
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:46
|
||||
msgid ""
|
||||
"Interfaces may not share the same name as configured members, policies or "
|
||||
"rules."
|
||||
msgstr ""
|
||||
"Интерфейсы не могут иметь то же имя, что и настроенные элементы, политики "
|
||||
"или правила."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:65
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:59
|
||||
msgid "Internet Protocol"
|
||||
msgstr "Протокол Интернета (IP)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:230
|
||||
msgid "Keep failure interval"
|
||||
msgstr "Сохранять интервал отказа"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:231
|
||||
msgid "Keep ping failure interval during failure state"
|
||||
msgstr "Сохранять интервал отказа пинг-запроса во время состояния отказа"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:61
|
||||
msgid "Last resort"
|
||||
msgstr "Крайнее средство"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:34
|
||||
msgid "Lines beginning with # are comments and are not executed."
|
||||
msgstr "Строки, начинающиеся с #, являются комментариями и не выполняются."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:21
|
||||
msgid ""
|
||||
"Load-balanced member interfaces distribute more traffic out those with "
|
||||
"higher weights."
|
||||
msgstr ""
|
||||
"Интерфейсы с балансировкой нагрузки распределяют больше трафика между "
|
||||
"интерфейсами с большим весом."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:19
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:117
|
||||
msgid "Logging"
|
||||
msgstr "Журналирование"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:22
|
||||
msgid "Loglevel"
|
||||
msgstr "Уровень журналирования"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:127
|
||||
msgid "Max TTL"
|
||||
msgstr "Максимальное TTL"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:81
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:90
|
||||
msgid ""
|
||||
"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or "
|
||||
"as a portrange (eg \"1024:2048\") without quotes"
|
||||
msgstr ""
|
||||
"Может быть введено как один или несколько портов (например, «22» или "
|
||||
"«80,443») или как диапазон портов (например, «1024:2048») без кавычек"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:75
|
||||
msgid "Member"
|
||||
msgstr "Узел"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:19
|
||||
msgid "Member interfaces with lower metrics are used first."
|
||||
msgstr "Интерфейсы с более низкими метриками используются в первую очередь."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:20
|
||||
msgid "Member interfaces with the same metric will be load-balanced."
|
||||
msgstr "Интерфейсы с одинаковой метрикой будут сбалансированы по нагрузке."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:54
|
||||
msgid "Member used"
|
||||
msgstr "Используемый узел"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:18
|
||||
msgid ""
|
||||
"Members are profiles attaching a metric and weight to an MWAN interface."
|
||||
msgstr "Элементы - это профили, прикрепляющие метрику и вес к интерфейсу MWAN."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:20
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:41
|
||||
msgid ""
|
||||
"Members may not share the same name as configured interfaces, policies or "
|
||||
"rules."
|
||||
msgstr ""
|
||||
"Элементы не могут иметь одинаковые имена с настроенными интерфейсами, "
|
||||
"политиками или правилами."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:288
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:57
|
||||
msgid "Metric"
|
||||
msgstr "Метрика"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:19
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:3
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:47
|
||||
msgid "MultiWAN Manager"
|
||||
msgstr "Менеджер MultiWAN"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:79
|
||||
msgid "MultiWAN Manager - Diagnostics"
|
||||
msgstr "Менеджер MultiWAN - Диагностика"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:10
|
||||
msgid "MultiWAN Manager - Globals"
|
||||
msgstr "Менеджер MultiWAN - Глобальные"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:21
|
||||
msgid "MultiWAN Manager - Interfaces"
|
||||
msgstr "Менеджер MultiWAN - Интерфейсы"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:17
|
||||
msgid "MultiWAN Manager - Members"
|
||||
msgstr "Менеджер MultiWAN - Элементы"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:26
|
||||
msgid "MultiWAN Manager - Notify"
|
||||
msgstr "Менеджер MultiWAN - Уведомления"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:93
|
||||
msgid "MultiWAN Manager - Overview"
|
||||
msgstr "Менеджер MultiWAN - Обзор"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:17
|
||||
msgid "MultiWAN Manager - Policies"
|
||||
msgstr "Менеджер MultiWAN - Политики"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:19
|
||||
msgid "MultiWAN Manager - Rules"
|
||||
msgstr "Менеджер MultiWAN - Правила"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/detail.js:12
|
||||
msgid "MultiWAN Manager - Status"
|
||||
msgstr "Менеджер MultiWAN - Статус"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/troubleshooting.js:12
|
||||
msgid "MultiWAN Manager - Troubleshooting"
|
||||
msgstr "Менеджер MultiWAN - Устранение неполадок"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:22
|
||||
msgid ""
|
||||
"Mwan3 requires that all interfaces have a unique metric configured in /etc/"
|
||||
"config/network."
|
||||
msgstr ""
|
||||
"Mwan3 требует, чтобы все интерфейсы имели уникальную метрику, настроенную в /"
|
||||
"etc/config/network."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:49
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:44
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:48
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:53
|
||||
msgid "Name length shall not exceed 15 characters"
|
||||
msgstr "Длина имени не должна превышать 15 символов"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:108
|
||||
msgid ""
|
||||
"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/"
|
||||
"youtube.com/youtube\")"
|
||||
msgstr ""
|
||||
"Имя IPset правила. Требуется правило IPset в /etc/dnsmasq.conf (например "
|
||||
"«ipset=/youtube.com/youtube»)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:24
|
||||
msgid "Names may contain characters A-Z, a-z, 0-9, _ and no spaces-"
|
||||
msgstr "Имена могут содержать символы A-Z, a-z, 0-9, _ и без пробелов и -"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:19
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:22
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:27
|
||||
msgid "Names may contain characters A-Z, a-z, 0-9, _ and no spaces."
|
||||
msgstr "Имена могут содержать символы A-Z, a-z, 0-9, _ и без пробелов."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:23
|
||||
msgid "Names must be 15 characters or less."
|
||||
msgstr "Имена должны состоять из 15 символов или менее."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:23
|
||||
msgid "Names must match the interface name found in /etc/config/network."
|
||||
msgstr "Имена должны совпадать с именем интерфейса из /etc/config/network."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:98
|
||||
msgid "No"
|
||||
msgstr "Нет"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:21
|
||||
msgid "No MWAN interfaces found"
|
||||
msgstr "Интерфейсы MWAN не найдены"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:44
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:52
|
||||
msgid "No Tracking"
|
||||
msgstr "Нет отслеживания"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:296
|
||||
msgid "No interface metric set!"
|
||||
msgstr "Не задана метрика интерфейса!"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:31
|
||||
msgid "Notes:"
|
||||
msgstr "Примечания:"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:30
|
||||
msgid "Notice"
|
||||
msgstr "Уведомление"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:99
|
||||
msgid "Notify"
|
||||
msgstr "Уведомить"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:62
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:38
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:46
|
||||
msgid "Offline"
|
||||
msgstr "Отключён"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:61
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:31
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:40
|
||||
msgid "Online"
|
||||
msgstr "Онлайн"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:15
|
||||
msgid "Overview"
|
||||
msgstr "Обзор"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:103
|
||||
msgid "Ping count"
|
||||
msgstr "Количество пинг-запросов"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:63
|
||||
msgid "Ping default gateway"
|
||||
msgstr "Пинг-запрос шлюза по умолчанию"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:198
|
||||
msgid "Ping interval"
|
||||
msgstr "Интервал пинг-запроса"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:214
|
||||
msgid "Ping interval during failure detection"
|
||||
msgstr "Интервал пинг-запросов во время обнаруженного отказа"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:236
|
||||
msgid "Ping interval during failure recovering"
|
||||
msgstr "Интервал пинг-запросов при восстановлении отказа"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:112
|
||||
msgid "Ping size"
|
||||
msgstr "Размер пакета пинг-запроса"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:191
|
||||
msgid "Ping timeout"
|
||||
msgstr "Время ожидания ответа пинг-запроса"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:64
|
||||
msgid "Ping tracking IP"
|
||||
msgstr "Пинг-запрос отслеживаемого IP"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:18
|
||||
msgid ""
|
||||
"Policies are profiles grouping one or more members controlling how Mwan3 "
|
||||
"distributes traffic."
|
||||
msgstr ""
|
||||
"Политики - это профили, объединяющие один или несколько элементов, "
|
||||
"управляющих распределением трафика в Mwan3."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:24
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:45
|
||||
msgid ""
|
||||
"Policies may not share the same name as configured interfaces, members or "
|
||||
"rules"
|
||||
msgstr ""
|
||||
"Политики не могут иметь одинаковые имена с настроенными интерфейсами, "
|
||||
"элементами или правилами"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:83
|
||||
msgid "Policy"
|
||||
msgstr "Политика"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:121
|
||||
msgid "Policy assigned"
|
||||
msgstr "Назначенная политика"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:66
|
||||
msgid "Protocol"
|
||||
msgstr "Протокол"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:35
|
||||
msgid ""
|
||||
"Put your custom mwan3 action here, they will be executed with each netifd "
|
||||
"hotplug interface event on interfaces for which mwan3 is enabled."
|
||||
msgstr ""
|
||||
"Поместите сюда ваши пользовательские действия mwan3, они будут выполняться "
|
||||
"при каждом событии интерфейса netifd hotplug на интерфейсах, для которых "
|
||||
"включён mwan3."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:235
|
||||
msgid "Recovery interval"
|
||||
msgstr "Интервал восстановления"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:168
|
||||
msgid "Recovery latency [ms]"
|
||||
msgstr "Задержка восстановления [мс]"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:181
|
||||
msgid "Recovery packet loss [%]"
|
||||
msgstr "Потери пакетов для восстановления [%]"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:39
|
||||
msgid "Routing table %d"
|
||||
msgstr "Таблица маршрутизации %d"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:36
|
||||
msgid "Routing table lookup"
|
||||
msgstr "Поиск таблицы маршрутизации"
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:91
|
||||
msgid "Rule"
|
||||
msgstr "Правило"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:21
|
||||
msgid "Rules are based on IP address, port or protocol."
|
||||
msgstr "Правила основаны на IP-адресе, порте или протоколе."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:22
|
||||
msgid "Rules are matched from top to bottom."
|
||||
msgstr "Правила сопоставляются сверху вниз."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:23
|
||||
msgid "Rules below a matching rule are ignored."
|
||||
msgstr "Правила, находящиеся ниже соответствующего правила, игнорируются."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:28
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:50
|
||||
msgid ""
|
||||
"Rules may not share the same name as configured interfaces, members or "
|
||||
"policies."
|
||||
msgstr ""
|
||||
"Правила не могут иметь одинаковые имена с настроенными интерфейсами, "
|
||||
"элементами или политиками."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:20
|
||||
msgid "Rules specify which traffic will use a particular MWAN policy."
|
||||
msgstr ""
|
||||
"Правила определяют, какой трафик будет использовать определённую политику "
|
||||
"MWAN."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:102
|
||||
msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"
|
||||
msgstr ""
|
||||
"Секунды. Допустимые значения: 1–1000000. По умолчанию 600, если значение не "
|
||||
"установлено"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:76
|
||||
msgid "Source address"
|
||||
msgstr "Адрес источника"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:80
|
||||
msgid "Source port"
|
||||
msgstr "Порт источника"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:66
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:83
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:107
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:23
|
||||
msgid "Status"
|
||||
msgstr "Статус"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:94
|
||||
msgid "Sticky"
|
||||
msgstr "Режим Sticky"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:101
|
||||
msgid "Sticky timeout"
|
||||
msgstr "Время ожидания режима Sticky"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:77
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:86
|
||||
msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"
|
||||
msgstr "Поддерживает CIDR нотацию (например «192.168.100.0/24») без кавычек"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/diagnostics.js:91
|
||||
msgid "Task"
|
||||
msgstr "Задача"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:29
|
||||
msgid "The file is also preserved during sysupgrade."
|
||||
msgstr "Этот файл также сохраняется при обновлении системы."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:33
|
||||
msgid ""
|
||||
"The first line of the script must be "#!/bin/sh" without quotes."
|
||||
msgstr "Первая строка скрипта должна быть "#!/bin/sh" без кавычек."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:37
|
||||
msgid ""
|
||||
"There are three main environment variables that are passed to this script."
|
||||
msgstr "В этот сценарий передаются три основные переменные среды окружения."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:289
|
||||
msgid ""
|
||||
"This displays the metric assigned to this interface in /etc/config/network"
|
||||
msgstr ""
|
||||
"Здесь отображается метрика, назначенная этому интерфейсу в файле /etc/config/"
|
||||
"network"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:32
|
||||
msgid "This file is interpreted as a shell script."
|
||||
msgstr "Этот файл интерпретируется как shell-скрипт."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:72
|
||||
msgid ""
|
||||
"This hostname or IP address will be pinged to determine if the link is up or "
|
||||
"down. Leave blank to assume interface is always online"
|
||||
msgstr ""
|
||||
"Имя хоста или IP-адрес для пинг-запроса, чтобы определить активно соединение "
|
||||
"или нет. Оставьте пустым, чтобы указать, что интерфейс всегда в сети"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:28
|
||||
msgid "This section allows you to modify the content of \"/etc/mwan3.user\"."
|
||||
msgstr "Этот раздел позволяет изменять содержимое файла \"/etc/mwan3.user\"."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:71
|
||||
msgid "Tracking hostname or IP address"
|
||||
msgstr "Отслеживамое имя хоста или IP-адрес"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:76
|
||||
msgid "Tracking method"
|
||||
msgstr "Метод отслеживания"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:98
|
||||
msgid "Tracking reliability"
|
||||
msgstr "Надёжность отслеживания"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:25
|
||||
msgid ""
|
||||
"Traffic destined for known (other than default) networks is handled by the "
|
||||
"main routing table."
|
||||
msgstr ""
|
||||
"Трафик, предназначенный для известных (кроме стандартных) сетей, "
|
||||
"обрабатывается основной таблицей маршрутизации."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:95
|
||||
msgid ""
|
||||
"Traffic from the same source IP address that previously matched this rule "
|
||||
"within the sticky timeout period will use the same WAN interface"
|
||||
msgstr ""
|
||||
"Трафик с того же IP-адреса источника, который ранее соответствовал этому "
|
||||
"правилу в период времени ожидания режима Sticky, будет использовать тот же "
|
||||
"интерфейс WAN"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:26
|
||||
msgid ""
|
||||
"Traffic matching a rule, but all WAN interfaces for that policy are down "
|
||||
"will be blackholed."
|
||||
msgstr ""
|
||||
"Трафик, соответствующий правилу, но все интерфейсы WAN для этой политики не "
|
||||
"работают, будет заблокирован."
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:24
|
||||
msgid "Traffic not matching any rule is routed using the main routing table."
|
||||
msgstr ""
|
||||
"Трафик, не соответствующий какому-либо правилу, направляется по основной "
|
||||
"таблице маршрутизации."
|
||||
|
||||
#: applications/luci-app-mwan3/root/usr/share/luci/menu.d/luci-app-mwan3.json:39
|
||||
msgid "Troubleshooting"
|
||||
msgstr "Устранение неполадок"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/notify.js:20
|
||||
msgid "Unable to save contents: %s"
|
||||
msgstr "Не удалось сохранить содержимое: %s"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:34
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/status/overview.js:48
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:43
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/status/include/90_mwan3.js:56
|
||||
msgid "Uptime"
|
||||
msgstr "Время работы"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:67
|
||||
msgid "View the content of /etc/protocols for protocol description"
|
||||
msgstr "Просмотр содержимого файла /etc/protocols для описания протокола"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/globals.js:29
|
||||
msgid "Warning"
|
||||
msgstr "Предупреждение"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/member.js:61
|
||||
msgid "Weight"
|
||||
msgstr "Вес"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:62
|
||||
msgid ""
|
||||
"When all policy members are offline use this behavior for matched traffic"
|
||||
msgstr ""
|
||||
"Когда все члены политики находятся в автономном режиме, используйте это "
|
||||
"поведение для сопоставляемого трафика"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:97
|
||||
msgid "Yes"
|
||||
msgstr "Да"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:65
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:127
|
||||
msgid "blackhole (drop)"
|
||||
msgstr "blackhole (отбросить)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:284
|
||||
msgid "connected (mwan3)"
|
||||
msgstr "подключено (connected, mwan3)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:66
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:128
|
||||
msgid "default (use main routing table)"
|
||||
msgstr "default (использовать основную таблицу маршрутизации)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:285
|
||||
msgid "disconnected (mwan3)"
|
||||
msgstr "отключено (disconnected, mwan3)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:283
|
||||
msgid "ifdown (netifd)"
|
||||
msgstr "отключено (ifdown, netifd)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/interface.js:282
|
||||
msgid "ifup (netifd)"
|
||||
msgstr "подключено (ifup, netifd)"
|
||||
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/policy.js:64
|
||||
#: applications/luci-app-mwan3/htdocs/luci-static/resources/view/mwan3/network/rule.js:126
|
||||
msgid "unreachable (reject)"
|
||||
msgstr "unreachable (отклонить)"
|
||||
|
||||
msgid "Show on overview"
|
||||
msgstr "Показать на главной"
|
||||
|
||||
msgid "Show MultiWAN status section on the overview page"
|
||||
msgstr "Показывать секцию состояния MultiWan на главной странице"
|
||||
|
||||
msgid "No available interfaces"
|
||||
msgstr "Нет доступных интерфейсов"
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q get mwan3.globals >/dev/null || {
|
||||
uci -q add mwan3 globals >/dev/null
|
||||
uci -q rename mwan3.@globals[-1]="globals" >/dev/null
|
||||
uci -q set mwan3.globals.local_source="none" >/dev/null
|
||||
uci commit mwan3
|
||||
}
|
||||
|
||||
exit 0
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2021 TDT AG <development@tdt.de>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
|
||||
#
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
IIF=1000
|
||||
FWMARK=2000
|
||||
ID=0
|
||||
|
||||
usage() {
|
||||
local status="$1"
|
||||
local msg="$2"
|
||||
if [ -n "$msg" ]; then
|
||||
echo "$msg"
|
||||
echo ""
|
||||
fi
|
||||
echo "Usage: $(basename "$0") <command>"
|
||||
echo "command:"
|
||||
echo " diag: diagnostic commands"
|
||||
echo " nftset: nft set commands"
|
||||
echo ""
|
||||
echo "diag <command> <iface>"
|
||||
echo "command:"
|
||||
echo " gateway <iface>: ping interface gateway"
|
||||
echo " tracking <iface>: ping interface tracking targets"
|
||||
echo " rules <iface>: check interface routing rules"
|
||||
echo " routes <iface>: check interface routing tables"
|
||||
echo ""
|
||||
echo "nftset <command>"
|
||||
echo "command:"
|
||||
echo " dump: show all configured nft set names"
|
||||
|
||||
exit "$status"
|
||||
}
|
||||
|
||||
diag_gateway() {
|
||||
local iface="$1"
|
||||
|
||||
local gw
|
||||
|
||||
network_get_gateway gw "${iface}"
|
||||
[ -z "$gw" ] && network_get_gateway gw "${iface}_4"
|
||||
|
||||
[ -z "$gw" ] && {
|
||||
echo "No gateway for interface ${iface} found."
|
||||
exit 2
|
||||
}
|
||||
|
||||
mwan3 use "$iface" "ping" "-c" "5" "-W" "1" "$gw"
|
||||
}
|
||||
|
||||
diag_tracking() {
|
||||
local iface="$1"
|
||||
|
||||
checkips() {
|
||||
local ip="$1"
|
||||
local iface="$2"
|
||||
|
||||
mwan3 use "$iface" "ping" "-c" "5" "-W" "1" "$ip"
|
||||
}
|
||||
|
||||
config_load mwan3
|
||||
config_list_foreach "$iface" "track_ip" checkips "$iface"
|
||||
}
|
||||
|
||||
iface_number() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
|
||||
let number++
|
||||
|
||||
[ "$cfg" = "$iface" ] && {
|
||||
ID="$number"
|
||||
}
|
||||
}
|
||||
|
||||
diag_rules() {
|
||||
local iface="$1"
|
||||
|
||||
local number=0
|
||||
local iif=0
|
||||
local fwmark=0
|
||||
|
||||
local iif_rule iif_result
|
||||
local fwmark_rule fwmark_result
|
||||
|
||||
config_load mwan3
|
||||
config_foreach iface_number 'interface' "$iface"
|
||||
|
||||
[ "$ID" = "0" ] && {
|
||||
echo "Unable to get mwan3 interface number for \"$iface\"."
|
||||
exit 2
|
||||
}
|
||||
|
||||
let "iif=$IIF+$ID"
|
||||
let "fwmark=$FWMARK+$ID"
|
||||
|
||||
iif_rule="$(ip rule | grep ${iif})"
|
||||
iif_result="$?"
|
||||
|
||||
fwmark_rule="$(ip rule | grep ${fwmark})"
|
||||
fwmark_result="$?"
|
||||
|
||||
if [ "$fwmark_result" = 0 ] && [ "$iif_result" = 0 ]; then
|
||||
echo "All required IP rules for interface \"$iface\" found"
|
||||
echo "$fwmark_rule"
|
||||
echo "$iif_rule"
|
||||
elif [ "$fwmark_result" = 1 ] && [ "$iif_result" = 0 ]; then
|
||||
echo "Only iif IP rule for interface \"$iface\" found"
|
||||
echo "$iif_rule"
|
||||
elif [ "$fwmark_result" = 0 ] && [ "$iif_result" = 1 ]; then
|
||||
echo "Only fwmark IP rule for interface \"$iface\" found"
|
||||
echo "$fwmark_rule"
|
||||
else
|
||||
echo "Missing fwmark and iif IP rule for interface \"$iface\""
|
||||
fi
|
||||
}
|
||||
|
||||
diag_routes() {
|
||||
local iface="$1"
|
||||
|
||||
local table table_result
|
||||
|
||||
config_load mwan3
|
||||
config_foreach iface_number 'interface' "$iface"
|
||||
|
||||
[ "$ID" = "0" ] && {
|
||||
echo "Unable to get mwan3 interface number for \"$iface\"."
|
||||
exit 2
|
||||
}
|
||||
|
||||
table="$(ip route list table $ID)"
|
||||
table_result="$?"
|
||||
|
||||
if [ "$table_result" = 0 ]; then
|
||||
echo "Routing table \"$ID\" for interface \"$iface\" found"
|
||||
echo "$table"
|
||||
else
|
||||
echo "Routing table \"$ID\" for interface \"$iface\" not found"
|
||||
fi
|
||||
}
|
||||
|
||||
diag_cmd() {
|
||||
case "$1" in
|
||||
gateway)
|
||||
diag_gateway "$2"
|
||||
;;
|
||||
tracking)
|
||||
diag_tracking "$2"
|
||||
;;
|
||||
rules)
|
||||
diag_rules "$2"
|
||||
;;
|
||||
routes)
|
||||
diag_routes "$2"
|
||||
;;
|
||||
*)
|
||||
usage "1" "Command not supported"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
nftset_dump() {
|
||||
nft -a list table inet mwan3 2>/dev/null | awk '/^\tset / && !/^\tset mwan3_/ {print $2}' | sort -u
|
||||
}
|
||||
|
||||
nftset_cmd() {
|
||||
case "$1" in
|
||||
dump)
|
||||
nftset_dump
|
||||
;;
|
||||
*)
|
||||
usage "1" "Command not supported"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main () {
|
||||
case "$1" in
|
||||
diag)
|
||||
diag_cmd "$2" "$3"
|
||||
;;
|
||||
nftset)
|
||||
nftset_cmd "$2"
|
||||
;;
|
||||
*)
|
||||
usage "1" "Command not supported"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"admin/status/mwan3": {
|
||||
"title": "MultiWAN Manager",
|
||||
"order": "600",
|
||||
"action": {
|
||||
"type": "firstchild"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [
|
||||
"luci-app-mwan3-status"
|
||||
]
|
||||
}
|
||||
},
|
||||
"admin/status/mwan3/overview": {
|
||||
"title": "Overview",
|
||||
"order": 10,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/status/overview"
|
||||
}
|
||||
},
|
||||
"admin/status/mwan3/detail": {
|
||||
"title": "Status",
|
||||
"order": 20,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/status/detail"
|
||||
}
|
||||
},
|
||||
"admin/status/mwan3/diagnostics": {
|
||||
"title": "Diagnostics",
|
||||
"order": 30,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/status/diagnostics"
|
||||
}
|
||||
},
|
||||
"admin/status/mwan3/troubleshooting": {
|
||||
"title": "Troubleshooting",
|
||||
"order": 40,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/status/troubleshooting"
|
||||
}
|
||||
},
|
||||
"admin/network/mwan3": {
|
||||
"title": "MultiWAN Manager",
|
||||
"order": "600",
|
||||
"action": {
|
||||
"type": "firstchild"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [
|
||||
"luci-app-mwan3"
|
||||
]
|
||||
}
|
||||
},
|
||||
"admin/network/mwan3/globals": {
|
||||
"title": "Globals",
|
||||
"order": 10,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/network/globals"
|
||||
}
|
||||
},
|
||||
"admin/network/mwan3/interface": {
|
||||
"title": "Interface",
|
||||
"order": 20,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/network/interface"
|
||||
}
|
||||
},
|
||||
"admin/network/mwan3/member": {
|
||||
"title": "Member",
|
||||
"order": 30,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/network/member"
|
||||
}
|
||||
},
|
||||
"admin/network/mwan3/policy": {
|
||||
"title": "Policy",
|
||||
"order": 40,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/network/policy"
|
||||
}
|
||||
},
|
||||
"admin/network/mwan3/rule": {
|
||||
"title": "Rule",
|
||||
"order": 50,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/network/rule"
|
||||
}
|
||||
},
|
||||
"admin/network/mwan3/notify": {
|
||||
"title": "Notify",
|
||||
"order": 60,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "mwan3/network/notify"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"luci-app-mwan3-status": {
|
||||
"description": "Grant access for luci-app-mwan3 status information",
|
||||
"read": {
|
||||
"cgi-io": [
|
||||
"exec"
|
||||
],
|
||||
"file": {
|
||||
"/usr/sbin/mwan3 status": [
|
||||
"exec"
|
||||
]
|
||||
},
|
||||
"ubus": {
|
||||
"mwan3": [
|
||||
"status"
|
||||
]
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
"file": {
|
||||
"/usr/libexec/luci-mwan3 diag gateway *": [
|
||||
"exec"
|
||||
],
|
||||
"/usr/libexec/luci-mwan3 diag tracking *": [
|
||||
"exec"
|
||||
],
|
||||
"/usr/libexec/luci-mwan3 diag rules *": [
|
||||
"exec"
|
||||
],
|
||||
"/usr/libexec/luci-mwan3 diag routes *": [
|
||||
"exec"
|
||||
],
|
||||
"/usr/sbin/mwan3 internal ipv4": [
|
||||
"exec"
|
||||
],
|
||||
"/usr/sbin/mwan3 ifup *": [
|
||||
"exec"
|
||||
],
|
||||
"/usr/sbin/mwan3 ifdown *": [
|
||||
"exec"
|
||||
]
|
||||
},
|
||||
"ubus": {
|
||||
"file": [
|
||||
"exec"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"luci-app-mwan3": {
|
||||
"description": "Grant access for luci-app-mwan3 configuration",
|
||||
"read": {
|
||||
"cgi-io": [
|
||||
"exec"
|
||||
],
|
||||
"file": {
|
||||
"/etc/mwan3.user": [
|
||||
"read"
|
||||
],
|
||||
"/usr/bin/httping": [
|
||||
"list"
|
||||
],
|
||||
"/usr/bin/nping": [
|
||||
"list"
|
||||
],
|
||||
"/usr/bin/arping": [
|
||||
"list"
|
||||
],
|
||||
"/usr/libexec/luci-mwan3 ipset dump": [
|
||||
"exec"
|
||||
]
|
||||
},
|
||||
"ubus": {
|
||||
"mwan3": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"uci": [
|
||||
"mwan3",
|
||||
"network"
|
||||
]
|
||||
},
|
||||
"write": {
|
||||
"file": {
|
||||
"/etc/mwan3.user": [
|
||||
"write"
|
||||
]
|
||||
},
|
||||
"uci": [
|
||||
"mwan3"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mwan3-ledhelper
|
||||
PKG_VERSION:=0.0.1
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=0.0.2
|
||||
PKG_RELEASE:=2
|
||||
PKG_MAINTAINER:=Konstantine Shevlakov <shevlakov@132lan.ru>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
@@ -13,6 +13,12 @@ define Package/$(PKG_NAME)
|
||||
DEPENDS:=+mwan3
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)-nft
|
||||
PKGARCH:=all
|
||||
TITLE:=MWAN3 Led Helper (nft variant)
|
||||
DEPENDS:=+mwan3-nft
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
Hotplug script to indicate led for mwan3 link states
|
||||
endef
|
||||
@@ -31,5 +37,10 @@ define Package/$(PKG_NAME)/install
|
||||
$(CP) ./root/* $(1)/
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)-nft/install
|
||||
$(CP) ./root/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)-nft))
|
||||
|
||||
+2
-2
@@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=natflow
|
||||
PKG_VERSION:=20260531
|
||||
PKG_RELEASE:=30
|
||||
PKG_RELEASE:=31
|
||||
|
||||
PKG_SOURCE:=$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=e75d2a375835d1d158604864199669343bdcdac6
|
||||
PKG_SOURCE_VERSION:=834324456603e21efc73521fa6b87dc0cbac7e30
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
Executable → Regular
+1
-1
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=pcie_mhi
|
||||
PKG_VERSION:=1.3.8
|
||||
PKG_RELEASE:=28
|
||||
PKG_RELEASE:=29
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
Reference in new issue
Block a user