From e55d184e9f9e14f60d0229687c0c4676ae4201c2 Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Mon, 18 Mar 2024 02:03:13 +0000 Subject: [PATCH] luci-app-pbr: update to 1.1.4-5 * sync with the principal package * add the status include file Signed-off-by: Stan Grishin --- applications/luci-app-pbr/Makefile | 7 +- .../luci-static/resources/pbr/status.js | 556 ++++++++++----- .../resources/view/pbr/overview.js | 650 +++++++++++------- .../resources/view/status/include/72_pbr.js | 88 +++ .../luci-app-pbr/po/templates/pbr.pot | 402 ++++++----- .../root/usr/libexec/rpcd/luci.pbr | 190 ++--- .../usr/share/rpcd/acl.d/luci-app-pbr.json | 8 + 7 files changed, 1154 insertions(+), 747 deletions(-) create mode 100644 applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js diff --git a/applications/luci-app-pbr/Makefile b/applications/luci-app-pbr/Makefile index 3b04a9500d43..6eee45f9bb00 100644 --- a/applications/luci-app-pbr/Makefile +++ b/applications/luci-app-pbr/Makefile @@ -1,15 +1,16 @@ -# Copyright 2017-2022 Stan Grishin (stangri@melmac.ca) +# Copyright 2017-2023 MOSSDeF, Stan Grishin (stangri@melmac.ca) # This is free software, licensed under the GNU General Public License v3. include $(TOPDIR)/rules.mk PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Stan Grishin -PKG_VERSION:=1.1.1-7 +PKG_VERSION:=1.1.4-5 LUCI_TITLE:=Policy Based Routing Service Web UI LUCI_DESCRIPTION:=Provides Web UI for Policy Based Routing Service. -LUCI_DEPENDS:=+luci-base +jsonfilter +pbr +LUCI_DEPENDS:=+luci-base +jsonfilter +pbr-service +LUCI_PKGARCH:=all PKG_PROVIDES:=luci-app-vpnbypass luci-app-vpn-policy-routing diff --git a/applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js b/applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js index 24f624c9452f..99a6e73844a3 100644 --- a/applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js +++ b/applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js @@ -3,7 +3,6 @@ "require ui"; "require rpc"; -"require uci"; "require form"; "require baseclass"; @@ -55,8 +54,8 @@ var _setInitAction = rpc.declare({ var RPC = { listeners: [], - on: function on(event, callback) { - var pair = { event: event, callback: callback } + on: function (event, callback) { + var pair = { event: event, callback: callback }; this.listeners.push(pair); return function unsubscribe() { this.listeners = this.listeners.filter(function (listener) { @@ -64,65 +63,77 @@ var RPC = { }); }.bind(this); }, - emit: function emit(event, data) { + emit: function (event, data) { this.listeners.forEach(function (listener) { if (listener.event === event) { listener.callback(data); } }); }, - getInitList: function getInitList(name) { - getInitList(name).then(function (result) { - this.emit('getInitList', result); - }.bind(this)); + getInitList: function (name) { + getInitList(name).then( + function (result) { + this.emit("getInitList", result); + }.bind(this) + ); }, - getInitStatus: function getInitStatus(name) { - getInitStatus(name).then(function (result) { - this.emit('getInitStatus', result); - }.bind(this)); + getInitStatus: function (name) { + getInitStatus(name).then( + function (result) { + this.emit("getInitStatus", result); + }.bind(this) + ); }, - getGateways: function getGateways(name) { - getGateways(name).then(function (result) { - this.emit('getGateways', result); - }.bind(this)); + getGateways: function (name) { + getGateways(name).then( + function (result) { + this.emit("getGateways", result); + }.bind(this) + ); }, - getPlatformSupport: function getPlatformSupport(name) { - getPlatformSupport(name).then(function (result) { - this.emit('getPlatformSupport', result); - }.bind(this)); + getPlatformSupport: function (name) { + getPlatformSupport(name).then( + function (result) { + this.emit("getPlatformSupport", result); + }.bind(this) + ); }, - getInterfaces: function getInterfaces(name) { - getInterfaces(name).then(function (result) { - this.emit('getInterfaces', result); - }.bind(this)); + getInterfaces: function (name) { + getInterfaces(name).then( + function (result) { + this.emit("getInterfaces", result); + }.bind(this) + ); }, - setInitAction: function setInitAction(name, action) { - _setInitAction(name, action).then(function (result) { - this.emit('setInitAction', result); - }.bind(this)); + setInitAction: function (name, action) { + _setInitAction(name, action).then( + function (result) { + this.emit("setInitAction", result); + }.bind(this) + ); }, -} +}; var status = baseclass.extend({ render: function () { return Promise.all([ - L.resolveDefault(getInitStatus(), {}), -// L.resolveDefault(getGateways(), {}), + L.resolveDefault(getInitStatus(pkg.Name), {}), + // L.resolveDefault(getGateways(pkg.Name), {}), ]).then(function (data) { -// var replyStatus = data[0]; -// var replyGateways = data[1]; + // var replyStatus = data[0]; + // var replyGateways = data[1]; var reply; var text; if (data[0] && data[0][pkg.Name]) { reply = data[0][pkg.Name]; - } - else { + } else { reply = { enabled: null, running: null, running_iptables: null, running_nft: null, + running_nft_file: null, version: null, gateways: null, errors: [], @@ -130,187 +141,351 @@ var status = baseclass.extend({ }; } - var header = E('h2', {}, _("Policy Based Routing - Status")); - var statusTitle = E('label', { class: 'cbi-value-title' }, _("Service Status")); + var header = E("h2", {}, _("Policy Based Routing - Status")); + var statusTitle = E( + "label", + { class: "cbi-value-title" }, + _("Service Status") + ); if (reply.version) { + text = _("Version %s").format(reply.version) + " - "; if (reply.running) { + text += _("Running"); if (reply.running_iptables) { - text = _("Running (version: %s using iptables)").format(reply.version); - } - else if (reply.running_nft) { - text = _("Running (version: %s using nft)").format(reply.version); + text += " (" + _("iptables mode") + ")."; + } else if (reply.running_nft_file) { + text += " (" + _("fw4 nft file mode") + ")."; + } else if (reply.running_nft) { + text += " (" + _("nft mode") + ")."; + } else { + text += "."; } - else { - text = _("Running (version: %s)").format(reply.version); - } - } - else { + } else { if (reply.enabled) { - text = _("Stopped (version: %s)").format(reply.version); - } - else { - text = _("Stopped (Disabled)"); + text += _("Stopped."); + } else { + text += _("Stopped (Disabled)."); } } - } - else { + } else { text = _("Not installed or not found"); } - var statusText = E('div', {}, text); - var statusField = E('div', { class: 'cbi-value-field' }, statusText); - var statusDiv = E('div', { class: 'cbi-value' }, [statusTitle, statusField]); + var statusText = E("div", {}, text); + var statusField = E("div", { class: "cbi-value-field" }, statusText); + var statusDiv = E("div", { class: "cbi-value" }, [ + statusTitle, + statusField, + ]); var gatewaysDiv = []; if (reply.gateways) { - var gatewaysTitle = E('label', { class: 'cbi-value-title' }, _("Service Gateways")); - text = _("The %s indicates default gateway. See the %sREADME%s for details.").format("", - "", "") - var gatewaysDescr = E('div', { class: 'cbi-value-description' }, text); - var gatewaysText = E('div', {}, reply.gateways); - var gatewaysField = E('div', { class: 'cbi-value-field' }, [gatewaysText, gatewaysDescr]); - gatewaysDiv = E('div', { class: 'cbi-value' }, [gatewaysTitle, gatewaysField]); + var gatewaysTitle = E( + "label", + { class: "cbi-value-title" }, + _("Service Gateways") + ); + text = _( + "The %s indicates default gateway. See the %sREADME%s for details." + ).format( + "", + '', + "" + ); + var gatewaysDescr = E("div", { class: "cbi-value-description" }, text); + var gatewaysText = E("div", {}, reply.gateways); + var gatewaysField = E("div", { class: "cbi-value-field" }, [ + gatewaysText, + gatewaysDescr, + ]); + gatewaysDiv = E("div", { class: "cbi-value" }, [ + gatewaysTitle, + gatewaysField, + ]); } var warningsDiv = []; if (reply.warnings && reply.warnings.length) { var textLabelsTable = { - warningResolverNotSupported: _("Resolver set (%s) is not supported on this system.").format(uci.get(pkg.Name, 'config', 'resolver_set')), - warningAGHVersionTooLow: _("Installed AdGuardHome (%s) doesn't support 'ipset_file' option."), + warningResolverNotSupported: _( + "Resolver set (%s) is not supported on this system." + ).format(L.uci.get(pkg.Name, "config", "resolver_set")), + warningAGHVersionTooLow: _( + "Installed AdGuardHome (%s) doesn't support 'ipset_file' option." + ), warningPolicyProcessCMD: _("%s"), - warningTorUnsetParams: _("Please unset 'src_addr', 'src_port' and 'dest_port' for policy '%s'"), - warningTorUnsetProto: _("Please unset 'proto' or set 'proto' to 'all' for policy '%s'"), - warningTorUnsetChainIpt: _("Please unset 'chain' or set 'chain' to 'PREROUTING' for policy '%s'"), - warningTorUnsetChainNft: _("Please unset 'chain' or set 'chain' to 'prerouting' for policy '%s'"), - warningInvalidOVPNConfig: _("Invalid OpenVPN config for %s interface"), - warningOutdatedWebUIApp: _("The WebUI application is outdated (version %s), please update it"), + warningTorUnsetParams: _( + "Please unset 'src_addr', 'src_port' and 'dest_port' for policy '%s'" + ), + warningTorUnsetProto: _( + "Please unset 'proto' or set 'proto' to 'all' for policy '%s'" + ), + warningTorUnsetChainIpt: _( + "Please unset 'chain' or set 'chain' to 'PREROUTING' for policy '%s'" + ), + warningTorUnsetChainNft: _( + "Please unset 'chain' or set 'chain' to 'prerouting' for policy '%s'" + ), + warningInvalidOVPNConfig: _( + "Invalid OpenVPN config for %s interface" + ), + warningOutdatedWebUIApp: _( + "The WebUI application is outdated (version %s), please update it" + ), + warningBadNftCallsInUserFile: _( + "Incompatible nft calls detected in user include file, disabling fw4 nft file support." + ), + warningDnsmasqInstanceNoConfdir: _( + "Dnsmasq instance (%s) targeted in settings, but it doesn't have its own confdir." + ), }; - var warningsTitle = E('label', { class: 'cbi-value-title' }, _("Service Warnings")); + var warningsTitle = E( + "label", + { class: "cbi-value-title" }, + _("Service Warnings") + ); var text = ""; - (reply.warnings).forEach(element => { + reply.warnings.forEach((element) => { if (element.id && textLabelsTable[element.id]) { - if (element.id !== 'warningPolicyProcessCMD') { - text += (textLabelsTable[element.id] + '.').format(element.extra || ' ') + "
"; + if (element.id !== "warningPolicyProcessCMD") { + text += + (textLabelsTable[element.id] + ".").format( + element.extra || " " + ) + "
"; } - } - else { - text += _("Unknown Warning.") + "
"; + } else { + text += _("Unknown warning") + "
"; } }); - var warningsText = E('div', {}, text); - var warningsField = E('div', { class: 'cbi-value-field' }, warningsText); - warningsDiv = E('div', { class: 'cbi-value' }, [warningsTitle, warningsField]); + var warningsText = E("div", {}, text); + var warningsField = E( + "div", + { class: "cbi-value-field" }, + warningsText + ); + warningsDiv = E("div", { class: "cbi-value" }, [ + warningsTitle, + warningsField, + ]); } var errorsDiv = []; if (reply.errors && reply.errors.length) { var textLabelsTable = { - errorConfigValidation: _("Config (%s) validation failure").format('/etc/config/' + pkg.Name), - errorNoIpFull: _("%s binary cannot be found").format('ip-full'), - errorNoIptables: _("%s binary cannot be found").format('iptables'), - errorNoIpset: _("Resolver set support (%s) requires ipset, but ipset binary cannot be found").format(uci.get(pkg.Name, 'config', 'resolver_set')), - errorNoNft: _("Resolver set support (%s) requires nftables, but nft binary cannot be found").format(uci.get(pkg.Name, 'config', 'resolver_set')), - errorResolverNotSupported: _("Resolver set (%s) is not supported on this system").format(uci.get(pkg.Name, 'config', 'resolver_set')), - errorServiceDisabled: _("The %s service is currently disabled").format(pkg.Name), - errorNoWanGateway: _("The %s service failed to discover WAN gateway").format(pkg.Name), - errorIpsetNameTooLong: _("The ipset name '%s' is longer than allowed 31 characters"), - errorNftsetNameTooLong: _("The nft set name '%s' is longer than allowed 31 characters"), - errorUnexpectedExit: _("Unexpected exit or service termination: '%s'"), - errorPolicyNoSrcDest: _("Policy '%s' has no source/destination parameters"), + errorConfigValidation: _("Config (%s) validation failure").format( + "/etc/config/" + pkg.Name + ), + errorNoIpFull: _("%s binary cannot be found").format("ip-full"), + errorNoIptables: _("%s binary cannot be found").format("iptables"), + errorNoIpset: _( + "Resolver set support (%s) requires ipset, but ipset binary cannot be found" + ).format(L.uci.get(pkg.Name, "config", "resolver_set")), + errorNoNft: _( + "Resolver set support (%s) requires nftables, but nft binary cannot be found" + ).format(L.uci.get(pkg.Name, "config", "resolver_set")), + errorResolverNotSupported: _( + "Resolver set (%s) is not supported on this system" + ).format(L.uci.get(pkg.Name, "config", "resolver_set")), + errorServiceDisabled: _( + "The %s service is currently disabled" + ).format(pkg.Name), + errorNoWanGateway: _( + "The %s service failed to discover WAN gateway" + ).format(pkg.Name), + errorIpsetNameTooLong: _( + "The ipset name '%s' is longer than allowed 31 characters" + ), + errorNftsetNameTooLong: _( + "The nft set name '%s' is longer than allowed 255 characters" + ), + errorUnexpectedExit: _( + "Unexpected exit or service termination: '%s'" + ), + errorPolicyNoSrcDest: _( + "Policy '%s' has no source/destination parameters" + ), errorPolicyNoInterface: _("Policy '%s' has no assigned interface"), - errorPolicyUnknownInterface: _("Policy '%s' has an unknown interface"), + errorPolicyUnknownInterface: _( + "Policy '%s' has an unknown interface" + ), errorPolicyProcessCMD: _("%s"), errorFailedSetup: _("Failed to set up '%s'"), errorFailedReload: _("Failed to reload '%s'"), errorUserFileNotFound: _("Custom user file '%s' not found or empty"), errorUserFileSyntax: _("Syntax error in custom user file '%s'"), errorUserFileRunning: _("Error running custom user file '%s'"), - errorUserFileNoCurl: _("Use of 'curl' is detected in custom user file '%s', but 'curl' isn't installed"), + errorUserFileNoCurl: _( + "Use of 'curl' is detected in custom user file '%s', but 'curl' isn't installed" + ), errorNoGateways: _("Failed to set up any gateway"), - errorResolver: _("Resolver %s"), - errorPolicyProcessNoIpv6: _("Skipping IPv6 policy '%s' as IPv6 support is disabled"), - errorPolicyProcessUnknownFwmark: _("Unknown packet mark for interface '%s'"), - errorPolicyProcessMismatchFamily: _("Mismatched IP family between in policy %s"), - errorPolicyProcessUnknownProtocol: _("Unknown protocol in policy %s"), - errorPolicyProcessInsertionFailed: _("Insertion failed for both IPv4 and IPv6 for policy %s"), - errorPolicyProcessInsertionFailedIpv4: _("Insertion failed for IPv4 for policy %s"), - errorInterfaceRoutingEmptyValues: _("Received empty tid/mark or interface name when setting up routing"), - errorFailedToResolve: _("Failed to resolve %s"), - errorInvalidOVPNConfig: _("Invalid OpenVPN config for %s interface"), + errorResolver: _("Resolver '%s'"), + errorPolicyProcessNoIpv6: _( + "Skipping IPv6 policy '%s' as IPv6 support is disabled" + ), + errorPolicyProcessUnknownFwmark: _( + "Unknown packet mark for interface '%s'" + ), + errorPolicyProcessMismatchFamily: _( + "Mismatched IP family between in policy '%s'" + ), + errorPolicyProcessUnknownProtocol: _( + "Unknown protocol in policy '%s'" + ), + errorPolicyProcessInsertionFailed: _( + "Insertion failed for both IPv4 and IPv6 for policy '%s'" + ), + errorPolicyProcessInsertionFailedIpv4: _( + "Insertion failed for IPv4 for policy '%s'" + ), + errorInterfaceRoutingEmptyValues: _( + "Received empty tid/mark or interface name when setting up routing" + ), + errorFailedToResolve: _("Failed to resolve '%s'"), + errorInvalidOVPNConfig: _( + "Invalid OpenVPN config for '%s' interface" + ), + errorNftFileInstall: _("Failed to install fw4 nft file '%s'"), + errorNoDownloadWithSecureReload: _( + "Policy '%s' refers to URL which can't be downloaded in 'secure_reload' mode!" + ), + errorDownloadUrlNoHttps: _( + "Failed to download '%s', HTTPS is not supported!" + ), + errorDownloadUrl: _("Failed to download '%s'!"), + errorFileSchemaRequiresCurl: _( + "The file:// schema requires curl, but it's not detected on this system!" + ), }; - var errorsTitle = E('label', { class: 'cbi-value-title' }, _("Service Errors")); + var errorsTitle = E( + "label", + { class: "cbi-value-title" }, + _("Service Errors") + ); var text = ""; - (reply.errors).forEach(element => { + reply.errors.forEach((element) => { if (element.id && textLabelsTable[element.id]) { - if (element.id !== 'errorPolicyProcessCMD') { - text += (textLabelsTable[element.id] + '!').format(element.extra || ' ') + "
"; + if (element.id !== "errorPolicyProcessCMD") { + text += + (textLabelsTable[element.id] + "!").format( + element.extra || " " + ) + "
"; } - } - else { - text += _("Unknown Error!") + "
"; + } else { + text += _("Unknown error!") + "
"; } }); - var errorsText = E('div', {}, text); - var errorsField = E('div', { class: 'cbi-value-field' }, errorsText); - errorsDiv = E('div', { class: 'cbi-value' }, [errorsTitle, errorsField]); + text += _("Errors encountered, please check the %sREADME%s!").format( + '', + "
" + ); + var errorsText = E("div", {}, text); + var errorsField = E("div", { class: "cbi-value-field" }, errorsText); + errorsDiv = E("div", { class: "cbi-value" }, [ + errorsTitle, + errorsField, + ]); } - var btn_gap = E('span', {}, '  '); - var btn_gap_long = E('span', {}, '        '); + var btn_gap = E("span", {}, "  "); + var btn_gap_long = E( + "span", + {}, + "        " + ); - var btn_start = E('button', { - 'class': 'btn cbi-button cbi-button-apply', - disabled: true, - click: function (ev) { - ui.showModal(null, [ - E('p', { 'class': 'spinning' }, _('Starting %s service').format(pkg.Name)) - ]); - return RPC.setInitAction(pkg.Name, 'start'); - } - }, _('Start')); + var btn_start = E( + "button", + { + class: "btn cbi-button cbi-button-apply", + disabled: true, + click: function (ev) { + ui.showModal(null, [ + E( + "p", + { class: "spinning" }, + _("Starting %s service").format(pkg.Name) + ), + ]); + return RPC.setInitAction(pkg.Name, "start"); + }, + }, + _("Start") + ); - var btn_action = E('button', { - 'class': 'btn cbi-button cbi-button-apply', - disabled: true, - click: function (ev) { - ui.showModal(null, [ - E('p', { 'class': 'spinning' }, _('Restarting %s service').format(pkg.Name)) - ]); - return RPC.setInitAction(pkg.Name, 'restart'); - } - }, _('Restart')); + var btn_action = E( + "button", + { + class: "btn cbi-button cbi-button-apply", + disabled: true, + click: function (ev) { + ui.showModal(null, [ + E( + "p", + { class: "spinning" }, + _("Restarting %s service").format(pkg.Name) + ), + ]); + return RPC.setInitAction(pkg.Name, "restart"); + }, + }, + _("Restart") + ); - var btn_stop = E('button', { - 'class': 'btn cbi-button cbi-button-reset', - disabled: true, - click: function (ev) { - ui.showModal(null, [ - E('p', { 'class': 'spinning' }, _('Stopping %s service').format(pkg.Name)) - ]); - return RPC.setInitAction(pkg.Name, 'stop'); - } - }, _('Stop')); + var btn_stop = E( + "button", + { + class: "btn cbi-button cbi-button-reset", + disabled: true, + click: function (ev) { + ui.showModal(null, [ + E( + "p", + { class: "spinning" }, + _("Stopping %s service").format(pkg.Name) + ), + ]); + return RPC.setInitAction(pkg.Name, "stop"); + }, + }, + _("Stop") + ); - var btn_enable = E('button', { - 'class': 'btn cbi-button cbi-button-apply', - disabled: true, - click: function (ev) { - ui.showModal(null, [ - E('p', { 'class': 'spinning' }, _('Enabling %s service').format(pkg.Name)) - ]); - return RPC.setInitAction(pkg.Name, 'enable'); - } - }, _('Enable')); + var btn_enable = E( + "button", + { + class: "btn cbi-button cbi-button-apply", + disabled: true, + click: function (ev) { + ui.showModal(null, [ + E( + "p", + { class: "spinning" }, + _("Enabling %s service").format(pkg.Name) + ), + ]); + return RPC.setInitAction(pkg.Name, "enable"); + }, + }, + _("Enable") + ); - var btn_disable = E('button', { - 'class': 'btn cbi-button cbi-button-reset', - disabled: true, - click: function (ev) { - ui.showModal(null, [ - E('p', { 'class': 'spinning' }, _('Disabling %s service').format(pkg.Name)) - ]); - return RPC.setInitAction(pkg.Name, 'disable'); - } - }, _('Disable')); + var btn_disable = E( + "button", + { + class: "btn cbi-button cbi-button-reset", + disabled: true, + click: function (ev) { + ui.showModal(null, [ + E( + "p", + { class: "spinning" }, + _("Disabling %s service").format(pkg.Name) + ), + ]); + return RPC.setInitAction(pkg.Name, "disable"); + }, + }, + _("Disable") + ); if (reply.enabled) { btn_enable.disabled = true; @@ -319,14 +494,12 @@ var status = baseclass.extend({ btn_start.disabled = true; btn_action.disabled = false; btn_stop.disabled = false; - } - else { + } else { btn_start.disabled = false; btn_action.disabled = true; btn_stop.disabled = true; } - } - else { + } else { btn_start.disabled = true; btn_action.disabled = true; btn_stop.disabled = true; @@ -334,22 +507,39 @@ var status = baseclass.extend({ btn_disable.disabled = true; } - var buttonsTitle = E('label', { class: 'cbi-value-title' }, _("Service Control")) - var buttonsText = E('div', {}, [btn_start, btn_gap, btn_action, btn_gap, btn_stop, btn_gap_long, btn_enable, btn_gap, btn_disable]); - var buttonsField = E('div', { class: 'cbi-value-field' }, buttonsText); - if (reply.version) { - var buttonsDiv = E('div', { class: 'cbi-value' }, [buttonsTitle, buttonsField]); - } - else { - var buttonsDiv = []; - } - - return E('div', {}, [header, statusDiv, gatewaysDiv, warningsDiv, errorsDiv, buttonsDiv]); + var buttonsTitle = E( + "label", + { class: "cbi-value-title" }, + _("Service Control") + ); + var buttonsText = E("div", {}, [ + btn_start, + btn_gap, + btn_action, + btn_gap, + btn_stop, + btn_gap_long, + btn_enable, + btn_gap, + btn_disable, + ]); + var buttonsField = E("div", { class: "cbi-value-field" }, buttonsText); + var buttonsDiv = reply.version + ? E("div", { class: "cbi-value" }, [buttonsTitle, buttonsField]) + : ""; + return E("div", {}, [ + header, + statusDiv, + gatewaysDiv, + warningsDiv, + errorsDiv, + buttonsDiv, + ]); }); }, }); -RPC.on('setInitAction', function (reply) { +RPC.on("setInitAction", function (reply) { ui.hideModal(); location.reload(); }); @@ -357,5 +547,5 @@ RPC.on('setInitAction', function (reply) { return L.Class.extend({ status: status, getInterfaces: getInterfaces, - getPlatformSupport: getPlatformSupport + getPlatformSupport: getPlatformSupport, }); diff --git a/applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js b/applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js index 2b5adaeb2ef9..99f8a502fa70 100644 --- a/applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js +++ b/applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js @@ -1,280 +1,404 @@ // Copyright 2022 Stan Grishin // This code wouldn't have been possible without help from [@vsviridov](https://github.com/vsviridov) -'use strict'; -'require form'; -'require rpc'; -'require uci'; -'require view'; -'require pbr.status as pbr'; +"use strict"; +"require form"; +"require rpc"; +"require view"; +"require pbr.status as pbr"; var pkg = { - get Name() { return 'pbr'; }, - get URL() { return 'https://docs.openwrt.melmac.net/' + pkg.Name + '/'; } + get Name() { + return "pbr"; + }, + + get URL() { + return "https://docs.openwrt.melmac.net/" + pkg.Name + "/"; + }, }; return view.extend({ load: function () { return Promise.all([ - uci.load(pkg.Name) + L.resolveDefault(pbr.getInterfaces(pkg.Name), {}), + L.resolveDefault(pbr.getPlatformSupport(pkg.Name), {}), + L.resolveDefault(L.uci.load(pkg.Name), {}), ]); }, - render: function () { - return Promise.all([ - L.resolveDefault(pbr.getInterfaces(), {}), - L.resolveDefault(pbr.getPlatformSupport(), {}), - ]).then(function (data) { - var arrInterfaces; - var replyPlatform; - var status, m, s, o; - - if (data[0] && data[0][pkg.Name] && data[0][pkg.Name].interfaces) { - arrInterfaces = data[0][pkg.Name].interfaces; - } - else { - arrInterfaces = ["wan"]; - } - - if (data[1] && data[1][pkg.Name]) { - replyPlatform = data[1][pkg.Name]; - } - else { - replyPlatform = { - ipset_installed: null, - nft_installed: null, - adguardhome_installed: null, - dnsmasq_installed: null, - unbound_installed: null, - adguardhome_ipset_support: null, - dnsmasq_ipset_support: null, - dnsmasq_nftset_support: null, - }; - } - - status = new pbr.status(); - m = new form.Map(pkg.Name, _("Policy Based Routing - Configuration")); - - s = m.section(form.NamedSection, 'config', pkg.Name); - s.tab("tab_basic", _("Basic Configuration")); - s.tab("tab_advanced", _("Advanced Configuration"), - _("%sWARNING:%s Please make sure to check the %sREADME%s before changing anything in this section! " + - "Change any of the settings below with extreme caution!%s").format( - "
    ", "", - "", "", "

")); - s.tab("tab_webui", _("Web UI Configuration")) - - o = s.taboption("tab_basic", form.ListValue, "verbosity", _("Output verbosity"), - _("Controls both system log and console output verbosity.")); - o.value("0", _("Suppress/No output")); - o.value("1", _("Condensed output")); - o.value("2", _("Verbose output")); - o.default = "2"; - - o = s.taboption("tab_basic", form.ListValue, "strict_enforcement", _("Strict enforcement"), - _("See the %sREADME%s for details.").format( - "", "")); - o.value("0", _("Do not enforce policies when their gateway is down")); - o.value("1", _("Strictly enforce policies when their gateway is down")); - o.default = "1"; - - var text = ""; - if (replyPlatform.adguardhome_ipset_support === null) { - text += _("The %s support is unknown.").format("adguardhome.ipset") + "
" - } - else if (!(replyPlatform.adguardhome_ipset_support)) { - text += _("The %s is not supported on this system.").format("adguardhome.ipset") + "
" - } - if (replyPlatform.dnsmasq_ipset_support === null) { - text += _("The %s support is unknown.").format("dnsmasq.ipset") + "
" - } - else if (!(replyPlatform.dnsmasq_ipset_support)) { - text += _("The %s is not supported on this system.").format("dnsmasq.ipset") + "
" - } - if (replyPlatform.dnsmasq_nftset_support === null) { - text += _("The %s support is unknown.").format("dnsmasq.nftset") + "
" - } - else if (!(replyPlatform.dnsmasq_nftset_support)) { - text += _("The %s is not supported on this system.").format("dnsmasq.nftset") + "
" - } - text += _("Please check the %sREADME%s before changing this option.").format( - "", ""); - o = s.taboption("tab_basic", form.ListValue, "resolver_set", _("Use resolver set support for domains"), text); - o.value("none", _("Disabled")); - if (replyPlatform.adguardhome_ipset_support) { - o.value("adguardhome.ipset", _("AdGuardHome ipset")); - o.default = ("adguardhome.ipset", _("AdGuardHome ipset")); - } - if (replyPlatform.dnsmasq_ipset_support) { - o.value("dnsmasq.ipset", _("Dnsmasq ipset")); - o.default = ("dnsmasq.ipset", _("Dnsmasq ipset")); - } - if (replyPlatform.dnsmasq_nftset_support) { - o.value("dnsmasq.nftset", _("Dnsmasq nft set")); - o.default = ("dnsmasq.nftset", _("Dnsmasq nft set")); + render: function (data) { + var status, m, s, o; + var reply = { + interfaces: (data[0] && + data[0][pkg.Name] && + data[0][pkg.Name].interfaces) || ["wan"], + platform: (data[1] && data[1][pkg.Name]) || { + ipset_installed: null, + nft_installed: null, + adguardhome_installed: null, + dnsmasq_installed: null, + unbound_installed: null, + adguardhome_ipset_support: null, + dnsmasq_ipset_support: null, + dnsmasq_nftset_support: null, + }, + }; + + status = new pbr.status(); + m = new form.Map(pkg.Name, _("Policy Based Routing - Configuration")); + + s = m.section(form.NamedSection, "config", pkg.Name); + s.tab("tab_basic", _("Basic Configuration")); + s.tab( + "tab_advanced", + _("Advanced Configuration"), + _( + "%sWARNING:%s Please make sure to check the %sREADME%s before changing anything in this section! " + + "Change any of the settings below with extreme caution!%s" + ).format( + "
    ", + "", + '', + "", + "

" + ) + ); + + s.tab("tab_webui", _("Web UI Configuration")); + + o = s.taboption( + "tab_basic", + form.ListValue, + "verbosity", + _("Output verbosity"), + _("Controls both system log and console output verbosity.") + ); + o.value("0", _("Suppress/No output")); + o.value("1", _("Condensed output")); + o.value("2", _("Verbose output")); + o.default = "2"; + + o = s.taboption( + "tab_basic", + form.ListValue, + "strict_enforcement", + _("Strict enforcement"), + _("See the %sREADME%s for details.").format( + '', + "" + ) + ); + o.value("0", _("Do not enforce policies when their gateway is down")); + o.value("1", _("Strictly enforce policies when their gateway is down")); + o.default = "1"; + + var text = ""; + if (reply.platform.adguardhome_ipset_support === null) { + text += + _("The %s support is unknown.").format("adguardhome.ipset") + + "
"; + } else if (!reply.platform.adguardhome_ipset_support) { + text += + _("The %s is not supported on this system.").format( + "adguardhome.ipset" + ) + "
"; + } + if (reply.platform.dnsmasq_ipset_support === null) { + text += + _("The %s support is unknown.").format("dnsmasq.ipset") + + "
"; + } else if (!reply.platform.dnsmasq_ipset_support) { + text += + _("The %s is not supported on this system.").format( + "dnsmasq.ipset" + ) + "
"; + } + if (reply.platform.dnsmasq_nftset_support === null) { + text += + _("The %s support is unknown.").format("dnsmasq.nftset") + + "
"; + } else if (!reply.platform.dnsmasq_nftset_support) { + text += + _("The %s is not supported on this system.").format( + "dnsmasq.nftset" + ) + "
"; + } + text += _( + "Please check the %sREADME%s before changing this option." + ).format( + '', + "" + ); + + o = s.taboption( + "tab_basic", + form.ListValue, + "resolver_set", + _("Use resolver set support for domains"), + text + ); + o.value("none", _("Disabled")); + if (reply.platform.adguardhome_ipset_support) { + o.value("adguardhome.ipset", _("AdGuardHome ipset")); + o.default = "adguardhome.ipset"; + } + if (reply.platform.dnsmasq_ipset_support) { + o.value("dnsmasq.ipset", _("Dnsmasq ipset")); + o.default = "dnsmasq.ipset"; + } + if (reply.platform.dnsmasq_nftset_support) { + o.value("dnsmasq.nftset", _("Dnsmasq nft set")); + o.default = "dnsmasq.nftset"; + } + + o = s.taboption( + "tab_basic", + form.ListValue, + "ipv6_enabled", + _("IPv6 Support") + ); + o.value("0", _("Disabled")); + o.value("1", _("Enabled")); + + o = s.taboption( + "tab_advanced", + form.DynamicList, + "supported_interface", + _("Supported Interfaces"), + _( + "Allows to specify the list of interface names (in lower case) to be explicitly supported by the service. " + + "Can be useful if your OpenVPN tunnels have dev option other than tun* or tap*." + ) + ); + o.optional = false; + + o = s.taboption( + "tab_advanced", + form.DynamicList, + "ignored_interface", + _("Ignored Interfaces"), + _( + "Allows to specify the list of interface names (in lower case) to be ignored by the service. " + + "Can be useful if running both VPN server and VPN client on the router." + ) + ); + o.optional = false; + + o = s.taboption( + "tab_advanced", + form.ListValue, + "rule_create_option", + _("Rule Create option"), + _("Select Add for -A/add and Insert for -I/Insert.") + ); + o.value("add", _("Add")); + o.value("insert", _("Insert")); + o.default = "add"; + + o = s.taboption( + "tab_advanced", + form.ListValue, + "icmp_interface", + _("Default ICMP Interface"), + _("Force the ICMP protocol interface.") + ); + o.value("", _("No Change")); + reply.interfaces.forEach((element) => { + if (element.toLowerCase() !== "ignore") { + o.value(element); } - - o = s.taboption("tab_basic", form.ListValue, "ipv6_enabled", _("IPv6 Support")); - o.value("0", _("Disabled")); - o.value("1", _("Enabled")); - - o = s.taboption("tab_advanced", form.DynamicList, "supported_interface", _("Supported Interfaces"), - _("Allows to specify the list of interface names (in lower case) to be explicitly supported by the service. " + - "Can be useful if your OpenVPN tunnels have dev option other than tun* or tap*.")); - o.optional = false; - - o = s.taboption("tab_advanced", form.DynamicList, "ignored_interface", _("Ignored Interfaces"), - _("Allows to specify the list of interface names (in lower case) to be ignored by the service. " + - "Can be useful if running both VPN server and VPN client on the router.")); - o.optional = false; - - o = s.taboption("tab_advanced", form.ListValue, "rule_create_option", _("Rule Create option"), - _("Select Add for -A/add and Insert for -I/Insert.")); - o.value("add", _("Add")); - o.value("insert", _("Insert")); - o.default = "add"; - - o = s.taboption("tab_advanced", form.ListValue, "icmp_interface", _("Default ICMP Interface"), - _("Force the ICMP protocol interface.")); - o.value("", _("No Change")); - arrInterfaces.forEach(element => { - if (element.toLowerCase() !== "ignore") { - o.value(element); - } - }); - o.rmempty = true; - - o = s.taboption("tab_advanced", form.Value, "wan_tid", _("WAN Table ID"), - _("Starting (WAN) Table ID number for tables created by the service.")); - o.rmempty = true; - o.placeholder = "201"; - o.datatype = "and(uinteger, min(201))"; - - o = s.taboption("tab_advanced", form.Value, "wan_mark", _("WAN Table FW Mark"), - _("Starting (WAN) FW Mark for marks used by the service. High starting mark is " + - "used to avoid conflict with SQM/QoS. Change with caution together with") + - " " + _("Service FW Mask") + "."); - o.rmempty = true; - o.placeholder = "010000"; - o.datatype = "hexstring"; - - o = s.taboption("tab_advanced", form.Value, "fw_mask", _("Service FW Mask"), - _("FW Mask used by the service. High mask is used to avoid conflict with SQM/QoS. " + - "Change with caution together with") + " " + _("WAN Table FW Mark") + "."); - o.rmempty = true; - o.placeholder = "ff0000"; - o.datatype = "hexstring"; - - o = s.taboption("tab_webui", form.ListValue, "webui_show_ignore_target", _("Add Ignore Target"), - _("Adds 'ignore' to the list of interfaces for policies. See the %sREADME%s for details.").format( - "", "")); - o.value("0", _("Disabled")) - o.value("1", _("Enabled")) - o.default = "0"; - o.optional = false; - - o = s.taboption("tab_webui", form.DynamicList, "webui_supported_protocol", _("Supported Protocols"), - _("Display these protocols in protocol column in Web UI.")); - o.optional = false; - - s = m.section(form.GridSection, 'policy', _('Policies'), - _("Name, interface and at least one other field are required. Multiple local and remote " + + }); + o.rmempty = true; + + o = s.taboption( + "tab_advanced", + form.Value, + "wan_mark", + _("WAN Table FW Mark"), + _( + "Starting (WAN) FW Mark for marks used by the service. High starting mark is " + + "used to avoid conflict with SQM/QoS. Change with caution together with" + ) + + " " + + _("Service FW Mask") + + "." + ); + o.rmempty = true; + o.placeholder = "010000"; + o.datatype = "hexstring"; + + o = s.taboption( + "tab_advanced", + form.Value, + "fw_mask", + _("Service FW Mask"), + _( + "FW Mask used by the service. High mask is used to avoid conflict with SQM/QoS. " + + "Change with caution together with" + ) + + " " + + _("WAN Table FW Mark") + + "." + ); + o.rmempty = true; + o.placeholder = "ff0000"; + o.datatype = "hexstring"; + + o = s.taboption( + "tab_webui", + form.ListValue, + "webui_show_ignore_target", + _("Add Ignore Target"), + _( + "Adds 'ignore' to the list of interfaces for policies. See the %sREADME%s for details." + ).format( + '', + "" + ) + ); + o.value("0", _("Disabled")); + o.value("1", _("Enabled")); + o.default = "0"; + o.optional = false; + + o = s.taboption( + "tab_webui", + form.DynamicList, + "webui_supported_protocol", + _("Supported Protocols"), + _("Display these protocols in protocol column in Web UI.") + ); + o.optional = false; + + s = m.section( + form.GridSection, + "policy", + _("Policies"), + _( + "Name, interface and at least one other field are required. Multiple local and remote " + "addresses/devices/domains and ports can be space separated. Placeholders below represent just " + - "the format/syntax and will not be used if fields are left blank.")); - s.rowcolors = true; - s.sortable = true; - s.anonymous = true; - s.addremove = true; - - o = s.option(form.Flag, "enabled", _("Enabled")); - o.default = "1"; - o.editable = true; - - o = s.option(form.Value, "name", _("Name")); - - o = s.option(form.Value, "src_addr", _("Local addresses / devices")); - o.datatype = "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network)))"; - o.rmempty = true; - o.default = ""; - - o = s.option(form.Value, "src_port", _("Local ports")); - o.datatype = "list(neg(or(portrange,port)))"; - o.placeholder = "0-65535"; - o.rmempty = true; - o.default = ""; - - o = s.option(form.Value, "dest_addr", _("Remote addresses / domains")); - o.datatype = "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network)))"; - o.rmempty = true; - o.default = ""; - - o = s.option(form.Value, "dest_port", _("Remote ports")); - o.datatype = "list(neg(or(portrange,port)))"; - o.placeholder = "0-65535"; - o.rmempty = true; - o.default = ""; - - o = s.option(form.ListValue, "proto", _("Protocol")); - var proto = L.toArray(uci.get(pkg.Name, "config", "webui_supported_protocol")); - if (!proto.length) { - proto = ["all", "tcp", "udp", "tcp udp", "icmp"] + "the format/syntax and will not be used if fields are left blank." + ) + ); + s.rowcolors = true; + s.sortable = true; + s.anonymous = true; + s.addremove = true; + + o = s.option(form.Flag, "enabled", _("Enabled")); + o.default = "1"; + o.editable = true; + + o = s.option(form.Value, "name", _("Name")); + + o = s.option(form.Value, "src_addr", _("Local addresses / devices")); + o.datatype = + "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network,string)))"; + o.rmempty = true; + o.default = ""; + + o = s.option(form.Value, "src_port", _("Local ports")); + o.datatype = "list(neg(or(portrange,port)))"; + o.placeholder = "0-65535"; + o.rmempty = true; + o.default = ""; + + o = s.option(form.Value, "dest_addr", _("Remote addresses / domains")); + o.datatype = + "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network,string)))"; + o.rmempty = true; + o.default = ""; + + o = s.option(form.Value, "dest_port", _("Remote ports")); + o.datatype = "list(neg(or(portrange,port)))"; + o.placeholder = "0-65535"; + o.rmempty = true; + o.default = ""; + + o = s.option(form.ListValue, "proto", _("Protocol")); + var proto = L.toArray( + L.uci.get(pkg.Name, "config", "webui_supported_protocol") + ); + if (!proto.length) { + proto = ["all", "tcp", "udp", "tcp udp", "icmp"]; + } + proto.forEach((element) => { + if (element === "all") { + o.value("", _("all")); + o.default = ""; + } else { + o.value(element.toLowerCase()); } - proto.forEach(element => { - if (element === "all") { - o.value("", _("all")); - o.default = ("", _("all")); - } - else { - o.value(element.toLowerCase()); - } - }); - o.rmempty = true; - - o = s.option(form.ListValue, "chain", _("Chain")); - o.value("", "prerouting"); - o.value("forward", "forward"); - o.value("input", "input"); - o.value("output", "output"); - o.value("postrouting", "postrouting"); - o.default = ("", "prerouting"); - o.rmempty = true; - - o = s.option(form.ListValue, "interface", _("Interface")); - arrInterfaces.forEach(element => { - o.value(element); - }); - o.datatype = "network"; - o.rmempty = false; - - s = m.section(form.NamedSection, 'config', pkg.Name, _("DSCP Tagging"), - _("Set DSCP tags (in range between 1 and 63) for specific interfaces. See the %sREADME%s for details.").format( - "", "")); - arrInterfaces.forEach(element => { - if (element.toLowerCase() !== "ignore") { - o = s.option(form.Value, element + "_dscp", element.toUpperCase() + " " + _("DSCP Tag")); - o.datatype = "and(uinteger, min(1), max(63))"; - } - }); - - s = m.section(form.GridSection, 'include', _("Custom User File Includes"), - _("Run the following user files after setting up but before restarting DNSMASQ. " + - "See the %sREADME%s for details.").format( - "", "")); - s.sortable = true; - s.anonymous = true; - s.addremove = true; - - o = s.option(form.Flag, "enabled", _("Enabled")); - o.optional = false; - o.editable = true; - o.rmempty = false; - - o = s.option(form.Value, "path", _("Path")); - o.optional = false; - o.editable = true; - o.rmempty = false; - - return Promise.all([status.render(), m.render()]); - }) - } + }); + o.rmempty = true; + + o = s.option(form.ListValue, "chain", _("Chain")); + o.value("", "prerouting"); + o.value("forward", "forward"); + o.value("input", "input"); + o.value("output", "output"); + o.value("postrouting", "postrouting"); + o.default = ""; + o.rmempty = true; + + o = s.option(form.ListValue, "interface", _("Interface")); + reply.interfaces.forEach((element) => { + o.value(element); + }); + o.datatype = "network"; + o.rmempty = false; + + s = m.section( + form.NamedSection, + "config", + pkg.Name, + _("DSCP Tagging"), + _( + "Set DSCP tags (in range between 1 and 63) for specific interfaces. See the %sREADME%s for details." + ).format( + '', + "" + ) + ); + reply.interfaces.forEach((element) => { + if (element.toLowerCase() !== "ignore") { + o = s.option( + form.Value, + element + "_dscp", + element.toUpperCase() + " " + _("DSCP Tag") + ); + o.datatype = "and(uinteger, min(1), max(63))"; + } + }); + + s = m.section( + form.GridSection, + "include", + _("Custom User File Includes"), + _( + "Run the following user files after setting up but before restarting DNSMASQ. " + + "See the %sREADME%s for details." + ).format( + '', + "" + ) + ); + s.sortable = true; + s.anonymous = true; + s.addremove = true; + + o = s.option(form.Flag, "enabled", _("Enabled")); + o.optional = false; + o.editable = true; + o.rmempty = false; + + o = s.option(form.Value, "path", _("Path")); + o.optional = false; + o.editable = true; + o.rmempty = false; + + return Promise.all([status.render(), m.render()]); + }, }); diff --git a/applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js b/applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js new file mode 100644 index 000000000000..536c3983c3e3 --- /dev/null +++ b/applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js @@ -0,0 +1,88 @@ +"require ui"; +"require rpc"; +"require form"; +"require baseclass"; + +var pkg = { + get Name() { + return "pbr"; + }, + get URL() { + return "https://docs.openwrt.melmac.net/" + pkg.Name + "/"; + }, +}; + +var getInitStatus = rpc.declare({ + object: "luci." + pkg.Name, + method: "getInitStatus", + params: ["name"], +}); + +return baseclass.extend({ + title: _("Policy Based Routing"), + + load: function () { + return Promise.all([getInitStatus(pkg.Name)]); + }, + + render: function (data) { + var reply; + if (data[0] && data[0][pkg.Name]) { + reply = data[0][pkg.Name]; + } else { + reply = { + enabled: null, + running: null, + running_iptables: null, + running_nft: null, + running_nft_file: null, + version: null, + gateways: null, + errors: [], + warnings: [], + }; + } + + var versionText, + statusText = "", + modeText = ""; + if (reply.version) { + versionText = reply.version; + if (reply.running) { + statusText = _("Active"); + if (reply.running_iptables) { + modeText = _("iptables mode"); + } else if (reply.running_nft_file) { + modeText = _("fw4 nft file mode"); + } else if (reply.running_nft) { + modeText = _("nft mode"); + } else { + modeText = _("unknown"); + } + } else { + if (reply.enabled) { + statusText = _("Inactive"); + } else { + statusText = _("Inactive (Disabled)"); + } + } + } else { + versionText = _("Not installed or not found"); + } + + var table = E("table", { class: "table", id: "pbr_status_table" }, [ + E("tr", { class: "tr table-titles" }, [ + E("th", { class: "th" }, _("Status")), + E("th", { class: "th" }, _("Version")), + E("th", { class: "th" }, _("Mode")), + ]), + E("tr", { class: "tr" }, [ + E("td", { class: "td" }, statusText), + E("td", { class: "td" }, versionText), + E("td", { class: "td" }, modeText), + ]), + ]); + + return table; + }, +}); diff --git a/applications/luci-app-pbr/po/templates/pbr.pot b/applications/luci-app-pbr/po/templates/pbr.pot index 8c5194160abb..a516be3d8e6a 100644 --- a/applications/luci-app-pbr/po/templates/pbr.pot +++ b/applications/luci-app-pbr/po/templates/pbr.pot @@ -1,174 +1,197 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:179 -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:221 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:215 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:310 msgid "%s" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:208 -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:209 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:277 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:278 msgid "%s binary cannot be found" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:61 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:56 msgid "" "%sWARNING:%s Please make sure to check the %sREADME%s before changing " "anything in this section! Change any of the settings below with extreme " "caution!%s" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:105 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:106 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:52 +msgid "Active" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:144 msgid "AdGuardHome ipset" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:133 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:196 msgid "Add" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:168 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:253 msgid "Add Ignore Target" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:169 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:255 msgid "" "Adds 'ignore' to the list of interfaces for policies. See the %sREADME%s for " "details." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:60 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:54 msgid "Advanced Configuration" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:122 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:171 msgid "" "Allows to specify the list of interface names (in lower case) to be " "explicitly supported by the service. Can be useful if your OpenVPN tunnels " "have dev option other than tun* or tap*." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:127 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:183 msgid "" "Allows to specify the list of interface names (in lower case) to be ignored " "by the service. Can be useful if running both VPN server and VPN client on " "the router." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:59 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:51 msgid "Basic Configuration" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:233 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:337 msgid "Chain" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:70 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:79 msgid "Condensed output" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:207 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:274 msgid "Config (%s) validation failure" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:68 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:76 msgid "Controls both system log and console output verbosity." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:259 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:379 msgid "Custom User File Includes" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:224 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:313 msgid "Custom user file '%s' not found or empty" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:254 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:370 msgid "DSCP Tag" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:249 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:357 msgid "DSCP Tagging" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:137 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:204 msgid "Default ICMP Interface" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:313 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:487 msgid "Disable" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:103 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:118 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:171 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:142 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:162 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:261 msgid "Disabled" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:309 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:481 msgid "Disabling %s service" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:177 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:271 msgid "Display these protocols in protocol column in Web UI." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:109 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:110 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:238 +msgid "" +"Dnsmasq instance (%s) targeted in settings, but it doesn't have its own " +"confdir." +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:148 msgid "Dnsmasq ipset" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:113 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:114 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:152 msgid "Dnsmasq nft set" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:77 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:93 msgid "Do not enforce policies when their gateway is down" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:302 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:468 msgid "Enable" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:119 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:172 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:189 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:267 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:163 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:262 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:290 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:392 msgid "Enabled" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:298 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:462 msgid "Enabling %s service" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:226 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:315 msgid "Error running custom user file '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:162 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:376 +msgid "Errors encountered, please check the %sREADME%s!" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:238 msgid "" "FW Mask used by the service. High mask is used to avoid conflict with SQM/" "QoS. Change with caution together with" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:223 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:353 +msgid "Failed to download '%s'!" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:351 +msgid "Failed to download '%s', HTTPS is not supported!" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:346 +msgid "Failed to install fw4 nft file '%s'" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:312 msgid "Failed to reload '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:237 -msgid "Failed to resolve %s" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:342 +msgid "Failed to resolve '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:222 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:311 msgid "Failed to set up '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:228 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:319 msgid "Failed to set up any gateway" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:138 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:205 msgid "Force the ICMP protocol interface." msgstr "" @@ -176,56 +199,77 @@ msgstr "" msgid "Grant UCI and file access for luci-app-pbr" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:117 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:160 msgid "IPv6 Support" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:126 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:181 msgid "Ignored Interfaces" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:134 -msgid "Insert" +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:64 +msgid "Inactive" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:66 +msgid "Inactive (Disabled)" msgstr "" #: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:235 -msgid "Insertion failed for IPv4 for policy %s" +msgid "" +"Incompatible nft calls detected in user include file, disabling fw4 nft file " +"support." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:234 -msgid "Insertion failed for both IPv4 and IPv6 for policy %s" +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:197 +msgid "Insert" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:337 +msgid "Insertion failed for IPv4 for policy '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:178 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:334 +msgid "Insertion failed for both IPv4 and IPv6 for policy '%s'" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:213 msgid "Installed AdGuardHome (%s) doesn't support 'ipset_file' option." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:242 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:346 msgid "Interface" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:184 -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:238 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:229 msgid "Invalid OpenVPN config for %s interface" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:195 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:344 +msgid "Invalid OpenVPN config for '%s' interface" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:296 msgid "Local addresses / devices" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:200 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:302 msgid "Local ports" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:232 -msgid "Mismatched IP family between in policy %s" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:328 +msgid "Mismatched IP family between in policy '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:193 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:77 +msgid "Mode" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:294 msgid "Name" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:181 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:280 msgid "" "Name, interface and at least one other field are required. Multiple local " "and remote addresses/devices/domains and ports can be space separated. " @@ -233,63 +277,73 @@ msgid "" "fields are left blank." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:139 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:207 msgid "No Change" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:157 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:171 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:70 msgid "Not installed or not found" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:67 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:75 msgid "Output verbosity" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:272 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:397 msgid "Path" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:100 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:129 msgid "Please check the %sREADME%s before changing this option." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:182 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:223 msgid "Please unset 'chain' or set 'chain' to 'PREROUTING' for policy '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:183 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:226 msgid "Please unset 'chain' or set 'chain' to 'prerouting' for policy '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:181 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:220 msgid "Please unset 'proto' or set 'proto' to 'all' for policy '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:180 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:217 msgid "Please unset 'src_addr', 'src_port' and 'dest_port' for policy '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:180 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:278 msgid "Policies" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:220 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:308 msgid "Policy '%s' has an unknown interface" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:219 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:306 msgid "Policy '%s' has no assigned interface" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:218 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:304 msgid "Policy '%s' has no source/destination parameters" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:56 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:348 +msgid "" +"Policy '%s' refers to URL which can't be downloaded in 'secure_reload' mode!" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:22 +msgid "Policy Based Routing" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:48 msgid "Policy Based Routing - Configuration" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:133 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:144 msgid "Policy Based Routing - Status" msgstr "" @@ -297,259 +351,277 @@ msgstr "" msgid "Policy Routing" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:217 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:320 msgid "Protocol" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:236 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:340 msgid "Received empty tid/mark or interface name when setting up routing" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:206 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:308 msgid "Remote addresses / domains" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:211 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:314 msgid "Remote ports" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:229 -msgid "Resolver %s" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:320 +msgid "Resolver '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:212 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:286 msgid "Resolver set (%s) is not supported on this system" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:177 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:210 msgid "Resolver set (%s) is not supported on this system." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:210 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:280 msgid "" "Resolver set support (%s) requires ipset, but ipset binary cannot be found" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:211 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:283 msgid "" "Resolver set support (%s) requires nftables, but nft binary cannot be found" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:280 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:430 msgid "Restart" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:276 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:424 msgid "Restarting %s service" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:131 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:193 msgid "Rule Create option" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:260 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:381 msgid "" "Run the following user files after setting up but before restarting DNSMASQ. " "See the %sREADME%s for details." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:138 -msgid "Running (version: %s using iptables)" -msgstr "" - -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:141 -msgid "Running (version: %s using nft)" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:153 +msgid "Running" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:144 -msgid "Running (version: %s)" -msgstr "" - -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:75 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:88 msgid "See the %sREADME%s for details." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:132 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:194 msgid "Select Add for -A/add and Insert for -I/Insert." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:337 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:513 msgid "Service Control" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:240 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:361 msgid "Service Errors" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:156 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:161 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:225 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:236 msgid "Service FW Mask" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:165 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:185 msgid "Service Gateways" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:134 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:148 msgid "Service Status" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:187 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:244 msgid "Service Warnings" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:250 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:359 msgid "" "Set DSCP tags (in range between 1 and 63) for specific interfaces. See the " "%sREADME%s for details." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:230 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:322 msgid "Skipping IPv6 policy '%s' as IPv6 support is disabled" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:269 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:411 msgid "Start" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:265 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:405 msgid "Starting %s service" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:154 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:221 msgid "" "Starting (WAN) FW Mark for marks used by the service. High starting mark is " "used to avoid conflict with SQM/QoS. Change with caution together with" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:148 -msgid "Starting (WAN) Table ID number for tables created by the service." +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:75 +msgid "Status" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:291 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:449 msgid "Stop" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:152 -msgid "Stopped (Disabled)" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:167 +msgid "Stopped (Disabled)." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:149 -msgid "Stopped (version: %s)" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:165 +msgid "Stopped." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:287 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:443 msgid "Stopping %s service" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:74 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:87 msgid "Strict enforcement" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:78 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:94 msgid "Strictly enforce policies when their gateway is down" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:121 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:169 msgid "Supported Interfaces" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:176 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:270 msgid "Supported Protocols" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:69 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:78 msgid "Suppress/No output" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:225 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:314 msgid "Syntax error in custom user file '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:166 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:188 msgid "The %s indicates default gateway. See the %sREADME%s for details." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:86 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:92 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:98 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:104 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:114 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:124 msgid "The %s is not supported on this system." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:214 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:292 msgid "The %s service failed to discover WAN gateway" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:213 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:289 msgid "The %s service is currently disabled" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:83 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:89 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:95 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:100 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:110 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:120 msgid "The %s support is unknown." msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:185 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:232 msgid "The WebUI application is outdated (version %s), please update it" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:215 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:355 +msgid "The file:// schema requires curl, but it's not detected on this system!" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:295 msgid "The ipset name '%s' is longer than allowed 31 characters" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:216 -msgid "The nft set name '%s' is longer than allowed 31 characters" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:298 +msgid "The nft set name '%s' is longer than allowed 255 characters" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:217 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:301 msgid "Unexpected exit or service termination: '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:249 -msgid "Unknown Error!" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:373 +msgid "Unknown error!" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:196 -msgid "Unknown Warning." +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:325 +msgid "Unknown packet mark for interface '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:231 -msgid "Unknown packet mark for interface '%s'" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:331 +msgid "Unknown protocol in policy '%s'" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:233 -msgid "Unknown protocol in policy %s" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:256 +msgid "Unknown warning" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:227 +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:317 msgid "" "Use of 'curl' is detected in custom user file '%s', but 'curl' isn't " "installed" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:102 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:139 msgid "Use resolver set support for domains" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:71 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:80 msgid "Verbose output" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:153 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:163 -msgid "WAN Table FW Mark" +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:76 +msgid "Version" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:147 -msgid "WAN Table ID" +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:151 +msgid "Version %s" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:65 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:219 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:242 +msgid "WAN Table FW Mark" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:69 msgid "Web UI Configuration" msgstr "" -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:224 -#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:225 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js:329 msgid "all" msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:157 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:56 +msgid "fw4 nft file mode" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:155 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:54 +msgid "iptables mode" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js:159 +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:58 +msgid "nft mode" +msgstr "" + +#: applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js:60 +msgid "unknown" +msgstr "" diff --git a/applications/luci-app-pbr/root/usr/libexec/rpcd/luci.pbr b/applications/luci-app-pbr/root/usr/libexec/rpcd/luci.pbr index 57af8010f03b..8412b0c4bc71 100755 --- a/applications/luci-app-pbr/root/usr/libexec/rpcd/luci.pbr +++ b/applications/luci-app-pbr/root/usr/libexec/rpcd/luci.pbr @@ -1,6 +1,6 @@ #!/bin/sh # Copyright 2022 Stan Grishin (stangri@melmac.ca) -# shellcheck disable=SC1091,SC2018,SC2019,SC2039,SC3043,SC3057,SC3060 +# shellcheck disable=SC2018,SC2019,SC2039,SC3043,SC3057,SC3060 # TechRef: https://openwrt.org/docs/techref/rpcd # TESTS @@ -11,41 +11,23 @@ # ubus -S call luci.pbr getGateways '{"name": "pbr" }' # ubus -S call luci.pbr getInterfaces '{"name": "pbr" }' -. /lib/functions.sh -. /lib/functions/network.sh -. /usr/share/libubox/jshn.sh - -readonly packageName="pbr" -# shellcheck disable=SC2155 -readonly ipset="$(command -v ipset)" -# shellcheck disable=SC2155 -readonly agh="$(command -v AdGuardHome)" -readonly aghConfigFile='/etc/adguardhome.yaml' -# shellcheck disable=SC2155 -readonly nft="$(command -v nft)" - -is_enabled() { uci -q get "${1}.config.enabled"; } -is_running_iptables() { iptables -t mangle -L | grep -q PBR_PREROUTING >/dev/null 2>&1; } -is_running_nft() { "$nft" list table inet fw4 | grep chain | grep -q pbr_mark_ >/dev/null 2>&1; } -is_running() { is_running_iptables || is_running_nft; } -get_version() { grep -m1 -A2 -w "^Package: $1$" /usr/lib/opkg/status | sed -n 's/Version: //p'; } -print_json_bool() { json_init; json_add_boolean "$1" "$2"; json_dump; json_cleanup; } -print_json_string() { json_init; json_add_string "$1" "$2"; json_dump; json_cleanup; } -logger() { /usr/bin/logger -t "$packageName" "$@"; } -ubus_get_status() { ubus call service list "{ 'name': '$packageName' }" | jsonfilter -e "@['${packageName}'].instances.main.data.status.${1}"; } -ubus_get_gateway() { ubus call service list "{ 'name': '$packageName' }" | jsonfilter -e "@['${packageName}'].instances.main.data.gateways[@.name='${1}']${2:+.$2}"; } -is_greater() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } -is_greater_or_equal() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" = "$2"; } -opkg_get_version() { grep -m1 -A1 "Package: $1$" '/usr/lib/opkg/status' | grep -m1 'Version: ' | sed 's|Version: \(.*\)|\1|'; } +readonly pbrFunctionsFile='/etc/init.d/pbr' +if [ -s "$pbrFunctionsFile" ]; then +# shellcheck source=../../../../../pbr/files/etc/init.d/pbr + . "$pbrFunctionsFile" +else + print_json_string 'error' "pbr init.d file ($pbrFunctionsFile) not found!" + logger -t pbr 'error' "pbr init.d file ($pbrFunctionsFile) not found!" +fi get_init_list() { local name name="$(basename "$1")" name="${name:-$packageName}" json_init - json_add_object "$name" - json_add_boolean 'enabled' "$(is_enabled "$name")" - if is_running "$name"; then + json_add_object "$packageName" + json_add_boolean 'enabled' "$(is_enabled "$packageName")" + if is_running "$packageName"; then json_add_boolean 'running' '1' else json_add_boolean 'running' '0' @@ -59,22 +41,27 @@ set_init_action() { local name action="$2" cmd name="$(basename "$1")" name="${name:-$packageName}" - if [ ! -f "/etc/init.d/$name" ]; then + if [ ! -f "/etc/init.d/$packageName" ]; then print_json_string 'error' 'Init script not found!' return fi case $action in enable) - cmd="uci -q set ${name}.config.enabled=1 && uci commit $name";; + cmd="/etc/init.d/${name} ${action}" + cmd="${cmd} && uci_set ${name} config enabled 1 && uci_commit $name" + ;; disable) - cmd="uci -q set ${name}.config.enabled=0 && uci commit $name";; + cmd="/etc/init.d/${name} ${action}" + cmd="${cmd} && uci_set ${name} config enabled 0 && uci_commit $name" + ;; start|stop|reload|restart) - cmd="/etc/init.d/${name} ${action}";; + cmd="/etc/init.d/${name} ${action}" + ;; esac - if [ -n "$cmd" ] && eval "${cmd}" 1>/dev/null 2>&1; then - print_json_bool "result" '1' + if [ -n "$cmd" ] && eval "$cmd" 1>/dev/null 2>&1; then + print_json_bool 'result' '1' else - print_json_bool "result" '0' + print_json_bool 'result' '0' fi } @@ -83,30 +70,35 @@ get_init_status() { name="$(basename "$1")" name="${name:-$packageName}" local version gateways warnings errors - [ -z "$version" ] && version="$(get_version "$name")" - [ -z "$version" ] && version="$(get_version "${name}-iptables")" - [ -z "$version" ] && version="$(get_version "${name}-netifd")" + [ -z "$version" ] && version="$(opkg_get_version "${name}")" + [ -z "$version" ] && version="$(opkg_get_version "${name}-iptables")" + [ -z "$version" ] && version="$(opkg_get_version "${name}-netifd")" gateways="$(ubus_get_status gateways | sed "s|\\\n|
|g;s|\(\\\033[^<]*\)|✓|g;")" warnings="$(ubus_get_status warnings)" errors="$(ubus_get_status errors)" json_init - json_add_object "$name" - json_add_boolean 'enabled' "$(is_enabled "$name")" - if is_running "$name"; then + json_add_object "$packageName" + json_add_boolean 'enabled' "$(is_enabled "$packageName")" + if is_running "$packageName"; then json_add_boolean 'running' '1' else json_add_boolean 'running' '0' fi - if is_running_iptables "$name"; then + if is_running_iptables "$packageName"; then json_add_boolean 'running_iptables' '1' else json_add_boolean 'running_iptables' '0' fi - if is_running_nft "$name"; then + if is_running_nft "$packageName"; then json_add_boolean 'running_nft' '1' else json_add_boolean 'running_nft' '0' fi + if is_running_nft_file "$packageName"; then + json_add_boolean 'running_nft_file' '1' + else + json_add_boolean 'running_nft_file' '0' + fi json_add_string 'version' "$version" json_add_string 'gateways' "$gateways" json_add_array 'errors' @@ -158,37 +150,12 @@ EOF json_cleanup } -check_ipset() { { [ -n "$ipset" ] && "$ipset" help hash:net; } >/dev/null 2>&1; } -check_nft() { [ -n "$nft" ]; } -check_agh() { [ -n "$agh" ] && [ -s "$aghConfigFile" ]; } -check_dnsmasq() { command -v dnsmasq >/dev/null 2>&1; } -check_unbound() { command -v unbound >/dev/null 2>&1; } -check_agh_ipset() { - check_ipset || return 1 - check_agh || return 1 - is_greater_or_equal "$($agh --version | sed 's|AdGuard Home, version v\(.*\)|\1|' | sed 's|-.*||')" '0.107.13' -} -check_dnsmasq_ipset() { - local o; - check_ipset || return 1 - check_dnsmasq || return 1 - o="$(dnsmasq -v 2>/dev/null)" - ! echo "$o" | grep -q 'no-ipset' && echo "$o" | grep -q 'ipset' -} -check_dnsmasq_nftset() { - local o; - check_nft || return 1 - check_dnsmasq || return 1 - o="$(dnsmasq -v 2>/dev/null)" - ! echo "$o" | grep -q 'no-nftset' && echo "$o" | grep -q 'nftset' -} - get_platform_support() { local name name="$(basename "$1")" name="${name:-$packageName}" json_init - json_add_object "$name" + json_add_object "$packageName" if check_ipset; then json_add_boolean 'ipset_installed' '1' else @@ -236,58 +203,16 @@ get_platform_support() { # shellcheck disable=SC3037 get_gateways() { - local name="${1:-$packageName}" - echo -en "{\"$name\":{\"gateways\":" - ubus call service list "{ 'name': '$name' }" | jsonfilter -e "@.${name}.instances.main.data.gateways" + echo -en "{\"$packageName\":{\"gateways\":" + ubus_get_gateways echo -en "}}" } -str_contains() { [ -n "$1" ] && [ -n "$2" ] && [ "${1//$2}" != "$1" ]; } -str_contains_word() { echo "$1" | grep -q -w "$2"; } -str_to_lower() { echo "$1" | tr 'A-Z' 'a-z'; } -str_to_upper() { echo "$1" | tr 'a-z' 'A-Z'; } -is_ignore_target() { [ "$(str_to_lower "$1")" = 'ignore' ]; } -is_dslite() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:6}" = "dslite" ]; } -is_l2tp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "l2tp" ]; } -is_oc() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:11}" = "openconnect" ]; } -is_ovpn() { local dev; network_get_device dev "$1"; [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; } -is_pptp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "pptp" ]; } -is_softether() { local dev; network_get_device dev "$1"; [ "${dev:0:4}" = "vpn_" ]; } -is_tor() { [ "$(str_to_lower "$1")" = "tor" ]; } -is_tor_running() { - local ret=0 - if [ -s "/etc/tor/torrc" ]; then - json_load "$(ubus call service list "{ 'name': 'tor' }")" - json_select 'tor'; json_select 'instances'; json_select 'instance1'; - json_get_var ret 'running'; json_cleanup - fi - if [ "$ret" = "0" ]; then return 1; else return 0; fi -} -is_wg() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:9}" = "wireguard" ]; } -is_tunnel() { is_dslite "$1" || is_l2tp "$1" || is_oc "$1" || is_ovpn "$1" || is_pptp "$1" || is_softether "$1" || is_tor "$1" || is_wg "$1"; } -is_wan() { [ "$1" = "$wanIface4" ] || { [ "${1##wan}" != "$1" ] && [ "${1##wan6}" = "$1" ]; } || [ "${1%%wan}" != "$1" ]; } -is_wan6() { [ -n "$wanIface6" ] && [ "$1" = "$wanIface6" ] || [ "${1/#wan6}" != "$1" ] || [ "${1/%wan6}" != "$1" ]; } -is_ignored_interface() { str_contains_word "$ignored_interface" "$1"; } -is_supported_interface() { str_contains_word "$supported_interface" "$1" || { ! is_ignored_interface "$1" && { is_wan "$1" || is_wan6 "$1" || is_tunnel "$1"; }; } || is_ignore_target "$1"; } -pbr_find_iface() { - local iface i param="$2" - [ "$param" = 'wan6' ] || param='wan' - "network_find_${param}" iface - is_tunnel "$iface" && unset iface - if [ -z "$iface" ]; then - for i in $ifacesAll; do - if "is_${param}" "$i"; then break; else unset i; fi - done - fi - eval "$1"='${iface:-$i}' -} -_find_firewall_wan_zone() { [ "$(uci -q get "firewall.${1}.name")" = "wan" ] && firewallWanZone="$1"; } -_build_ifaces_all() { ifacesAll="${ifacesAll}${1} "; } -_build_ifaces_supported() { is_supported_interface "$1" && ! str_contains "$ifacesSupported" "$1" && ifacesSupported="${ifacesSupported}${1} "; } get_supported_interfaces() { - local name i - name="$(basename "$1")" - name="${name:-$packageName}" + _find_firewall_wan_zone() { [ "$(uci_get 'firewall' "$1" 'name')" = "wan" ] && firewallWanZone="$1"; } + _build_ifaces_all() { ifacesAll="${ifacesAll}${1} "; } + _build_ifaces_supported() { is_supported_interface "$1" && ! str_contains "$ifacesSupported" "$1" && ifacesSupported="${ifacesSupported}${1} "; } + local i local firewallWanZone local ifacesAll ifacesSupported local webui_show_ignore_target @@ -304,19 +229,18 @@ get_supported_interfaces() { pbr_find_iface wanIface6 'wan6' config_load 'firewall' config_foreach _find_firewall_wan_zone 'zone' - for i in $(uci -q get "firewall.${firewallWanZone}.network"); do + for i in $(uci_get 'firewall' "$firewallWanZone" 'network'); do is_supported_interface "$i" && ! str_contains "$ifacesSupported" "$1" && ifacesSupported="${ifacesSupported}${i} " done config_load 'network' config_foreach _build_ifaces_supported 'interface' - if is_tor_running; then - ifacesSupported="$ifacesSupported tor" - fi - if [ "$webui_show_ignore_target" -eq "1" ]; then - ifacesSupported="$ifacesSupported ignore" - fi + is_tor_running && ifacesSupported="$ifacesSupported tor" + for i in $supported_interface; do + is_xray "$i" && ifacesSupported="$ifacesSupported $i" + done + [ "$webui_show_ignore_target" -eq "1" ] && ifacesSupported="$ifacesSupported ignore" json_init - json_add_object "$name" + json_add_object "$packageName" json_add_array 'interfaces' for i in $ifacesSupported; do json_add_string '' "$i" @@ -359,35 +283,35 @@ case "$1" in json_load "$input" json_get_var name 'name' json_cleanup - get_gateways "$name" + get_gateways "$packageName" ;; getInitList) read -r input json_load "$input" json_get_var name 'name' json_cleanup - get_init_list "$name" + get_init_list "$packageName" ;; getInitStatus) read -r input json_load "$input" json_get_var name 'name' json_cleanup - get_init_status "$name" + get_init_status "$packageName" ;; getInterfaces) read -r input json_load "$input" json_get_var name 'name' json_cleanup - get_supported_interfaces "$name" + get_supported_interfaces "$packageName" ;; getPlatformSupport) read -r input json_load "$input" json_get_var name 'name' json_cleanup - get_platform_support "$name" + get_platform_support "$packageName" ;; setInitAction) read -r input @@ -395,7 +319,7 @@ case "$1" in json_get_var name 'name' json_get_var action 'action' json_cleanup - set_init_action "$name" "$action" + set_init_action "$packageName" "$action" ;; esac ;; diff --git a/applications/luci-app-pbr/root/usr/share/rpcd/acl.d/luci-app-pbr.json b/applications/luci-app-pbr/root/usr/share/rpcd/acl.d/luci-app-pbr.json index 39178f3790ec..6c2f7de6d78a 100644 --- a/applications/luci-app-pbr/root/usr/share/rpcd/acl.d/luci-app-pbr.json +++ b/applications/luci-app-pbr/root/usr/share/rpcd/acl.d/luci-app-pbr.json @@ -11,6 +11,14 @@ "getPlatformSupport" ] }, + "file": { + "/usr/share/nftables.d/ruleset-post/30-pbr.nft": [ + "read" + ], + "/var/run/pbr.nft": [ + "read" + ] + }, "uci": [ "pbr" ]