summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-pbr
diff options
context:
space:
mode:
authorStan Grishin <stangri@melmac.ca>2024-03-18 02:03:13 +0000
committerStan Grishin <stangri@melmac.ca>2024-03-18 02:04:15 +0000
commite55d184e9f9e14f60d0229687c0c4676ae4201c2 (patch)
tree5de335884569377eb4d13c980c9d7f3210157b70 /applications/luci-app-pbr
parentf2a49104c4839cc61c0c6a32cf0b616ca7b7d667 (diff)
luci-app-pbr: update to 1.1.4-5
* sync with the principal package * add the status include file Signed-off-by: Stan Grishin <stangri@melmac.ca>
Diffstat (limited to 'applications/luci-app-pbr')
-rw-r--r--applications/luci-app-pbr/Makefile7
-rw-r--r--applications/luci-app-pbr/htdocs/luci-static/resources/pbr/status.js556
-rw-r--r--applications/luci-app-pbr/htdocs/luci-static/resources/view/pbr/overview.js650
-rw-r--r--applications/luci-app-pbr/htdocs/luci-static/resources/view/status/include/72_pbr.js88
-rw-r--r--applications/luci-app-pbr/po/templates/pbr.pot402
-rwxr-xr-xapplications/luci-app-pbr/root/usr/libexec/rpcd/luci.pbr190
-rw-r--r--applications/luci-app-pbr/root/usr/share/rpcd/acl.d/luci-app-pbr.json8
7 files changed, 1154 insertions, 747 deletions
diff --git a/applications/luci-app-pbr/Makefile b/applications/luci-app-pbr/Makefile
index 3b04a9500d..6eee45f9bb 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 <stangri@melmac.ca>
-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 24f624c945..99a6e73844 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("<strong>✓</strong>",
- "<a href=\"" + pkg.URL + "#a-word-about-default-routing \" target=\"_blank\">", "</a>")
- 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(
+ "<strong>✓</strong>",
+ '<a href="' + pkg.URL + '#AWordAboutDefaultRouting" target="_blank">',
+ "</a>"
+ );
+ 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 || ' ') + "<br />";
+ if (element.id !== "warningPolicyProcessCMD") {
+ text +=
+ (textLabelsTable[element.id] + ".").format(
+ element.extra || " "
+ ) + "<br />";
}
- }
- else {
- text += _("Unknown Warning.") + "<br />";
+ } else {
+ text += _("Unknown warning") + "<br />";
}
});
- 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 || ' ') + "<br />";
+ if (element.id !== "errorPolicyProcessCMD") {
+ text +=
+ (textLabelsTable[element.id] + "!").format(
+ element.extra || " "
+ ) + "<br />";
}
- }
- else {
- text += _("Unknown Error!") + "<br />";
+ } else {
+ text += _("Unknown error!") + "<br />";
}
});
- 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(
+ '<a href="' + pkg.URL + '" target="_blank">',
+ "</a><br />"
+ );
+ 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', {}, '&#160;&#160;');
- var btn_gap_long = E('span', {}, '&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;');
+ var btn_gap = E("span", {}, "&#160;&#160;");
+ var btn_gap_long = E(
+ "span",
+ {},
+ "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;"
+ );
- 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 2b5adaeb2e..99f8a502fa 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 <stangri@melmac.ca>
// 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(
- "<br/>&#160;&#160;&#160;&#160;<b>", "</b>",
- "<a href=\"" + pkg.URL + "#service-configuration-settings\" target=\"_blank\">", "</a>", "<br/><br/>"));
- 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(
- "<a href=\"" + pkg.URL + "#strict-enforcement\" target=\"_blank\">", "</a>"));
- 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("<i>adguardhome.ipset</i>") + "<br />"
- }
- else if (!(replyPlatform.adguardhome_ipset_support)) {
- text += _("The %s is not supported on this system.").format("<i>adguardhome.ipset</i>") + "<br />"
- }
- if (replyPlatform.dnsmasq_ipset_support === null) {
- text += _("The %s support is unknown.").format("<i>dnsmasq.ipset</i>") + "<br />"
- }
- else if (!(replyPlatform.dnsmasq_ipset_support)) {
- text += _("The %s is not supported on this system.").format("<i>dnsmasq.ipset</i>") + "<br />"
- }
- if (replyPlatform.dnsmasq_nftset_support === null) {
- text += _("The %s support is unknown.").format("<i>dnsmasq.nftset</i>") + "<br />"
- }
- else if (!(replyPlatform.dnsmasq_nftset_support)) {
- text += _("The %s is not supported on this system.").format("<i>dnsmasq.nftset</i>") + "<br />"
- }
- text += _("Please check the %sREADME%s before changing this option.").format(
- "<a href=\"" + pkg.URL + "#use-resolvers-set-support\" target=\"_blank\">", "</a>");
- 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(
+ "<br/>&#160;&#160;&#160;&#160;<b>",
+ "</b>",
+ '<a href="' +
+ pkg.URL +
+ '#ServiceConfigurationSettings" target="_blank">',
+ "</a>",
+ "<br/><br/>"
+ )
+ );
+
+ 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(
+ '<a href="' + pkg.URL + '#StrictEnforcement" target="_blank">',
+ "</a>"
+ )
+ );
+ 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("<i>adguardhome.ipset</i>") +
+ "<br />";
+ } else if (!reply.platform.adguardhome_ipset_support) {
+ text +=
+ _("The %s is not supported on this system.").format(
+ "<i>adguardhome.ipset</i>"
+ ) + "<br />";
+ }
+ if (reply.platform.dnsmasq_ipset_support === null) {
+ text +=
+ _("The %s support is unknown.").format("<i>dnsmasq.ipset</i>") +
+ "<br />";
+ } else if (!reply.platform.dnsmasq_ipset_support) {
+ text +=
+ _("The %s is not supported on this system.").format(
+ "<i>dnsmasq.ipset</i>"
+ ) + "<br />";
+ }
+ if (reply.platform.dnsmasq_nftset_support === null) {
+ text +=
+ _("The %s support is unknown.").format("<i>dnsmasq.nftset</i>") +
+ "<br />";
+ } else if (!reply.platform.dnsmasq_nftset_support) {
+ text +=
+ _("The %s is not supported on this system.").format(
+ "<i>dnsmasq.nftset</i>"
+ ) + "<br />";
+ }
+ text += _(
+ "Please check the %sREADME%s before changing this option."
+ ).format(
+ '<a href="' + pkg.URL + '#UseResolversSetSupport" target="_blank">',
+ "</a>"
+ );
+
+ 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(
- "<a href=\"" + pkg.URL + "#ignore-target\" target=\"_blank\">", "</a>"));
- 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(
+ '<a href="' + pkg.URL + '#IgnoreTarget" target="_blank">',
+ "</a>"
+ )
+ );
+ 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(
- "<a href=\"" + pkg.URL + "#dscp-tag-based-policies" + "\" target=\"_blank\">", "</a>"));
- 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(
- "<a href=\"" + pkg.URL + "#custom-user-files\" target=\"_blank\">", "</a>"));
- 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(
+ '<a href="' + pkg.URL + "#DSCPTag-BasedPolicies" + '" target="_blank">',
+ "</a>"
+ )
+ );
+ 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(
+ '<a href="' + pkg.URL + '#CustomUserFiles" target="_blank">',
+ "</a>"
+ )
+ );
+ 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 0000000000..536c3983c3
--- /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 8c5194160a..a516be3d8e 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 57af8010f0..8412b0c4bc 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|<br />|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 39178f3790..6c2f7de6d7 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"
]