1 // Copyright 2022 Stan Grishin <stangri@melmac.ca>
2 // This code wouldn't have been possible without help from [@vsviridov](https://github.com/vsviridov)
8 "require pbr.status as pbr";
16 return "https://docs.openwrt.melmac.net/" + pkg
.Name
+ "/";
23 L
.resolveDefault(pbr
.getInterfaces(pkg
.Name
), {}),
24 L
.resolveDefault(pbr
.getPlatformSupport(pkg
.Name
), {}),
25 L
.resolveDefault(L
.uci
.load(pkg
.Name
), {}),
29 render: function (data
) {
32 interfaces
: (data
[0] &&
34 data
[0][pkg
.Name
].interfaces
) || ["wan"],
35 platform
: (data
[1] && data
[1][pkg
.Name
]) || {
36 ipset_installed
: null,
38 adguardhome_installed
: null,
39 dnsmasq_installed
: null,
40 unbound_installed
: null,
41 adguardhome_ipset_support
: null,
42 dnsmasq_ipset_support
: null,
43 dnsmasq_nftset_support
: null,
47 status
= new pbr
.status();
48 m
= new form
.Map(pkg
.Name
, _("Policy Based Routing - Configuration"));
50 s
= m
.section(form
.NamedSection
, "config", pkg
.Name
);
51 s
.tab("tab_basic", _("Basic Configuration"));
54 _("Advanced Configuration"),
56 "%sWARNING:%s Please make sure to check the %sREADME%s before changing anything in this section! " +
57 "Change any of the settings below with extreme caution!%s"
59 "<br/>    <b>",
63 '#ServiceConfigurationSettings" target="_blank">',
69 s
.tab("tab_webui", _("Web UI Configuration"));
75 _("Output verbosity"),
76 _("Controls both system log and console output verbosity.")
78 o
.value("0", _("Suppress/No output"));
79 o
.value("1", _("Condensed output"));
80 o
.value("2", _("Verbose output"));
87 _("Strict enforcement"),
88 _("See the %sREADME%s for details.").format(
89 '<a href="' + pkg
.URL
+ '#StrictEnforcement" target="_blank">',
93 o
.value("0", _("Do not enforce policies when their gateway is down"));
94 o
.value("1", _("Strictly enforce policies when their gateway is down"));
98 if (reply
.platform
.adguardhome_ipset_support
=== null) {
100 _("The %s support is unknown.").format("<i>adguardhome.ipset</i>") +
102 } else if (!reply
.platform
.adguardhome_ipset_support
) {
104 _("The %s is not supported on this system.").format(
105 "<i>adguardhome.ipset</i>"
108 if (reply
.platform
.dnsmasq_ipset_support
=== null) {
110 _("The %s support is unknown.").format("<i>dnsmasq.ipset</i>") +
112 } else if (!reply
.platform
.dnsmasq_ipset_support
) {
114 _("The %s is not supported on this system.").format(
115 "<i>dnsmasq.ipset</i>"
118 if (reply
.platform
.dnsmasq_nftset_support
=== null) {
120 _("The %s support is unknown.").format("<i>dnsmasq.nftset</i>") +
122 } else if (!reply
.platform
.dnsmasq_nftset_support
) {
124 _("The %s is not supported on this system.").format(
125 "<i>dnsmasq.nftset</i>"
129 "Please check the %sREADME%s before changing this option."
131 '<a href="' + pkg
.URL
+ '#UseResolversSetSupport" target="_blank">',
139 _("Use resolver set support for domains"),
142 o
.value("none", _("Disabled"));
143 if (reply
.platform
.adguardhome_ipset_support
) {
144 o
.value("adguardhome.ipset", _("AdGuardHome ipset"));
145 o
.default = "adguardhome.ipset";
147 if (reply
.platform
.dnsmasq_ipset_support
) {
148 o
.value("dnsmasq.ipset", _("Dnsmasq ipset"));
149 o
.default = "dnsmasq.ipset";
151 if (reply
.platform
.dnsmasq_nftset_support
) {
152 o
.value("dnsmasq.nftset", _("Dnsmasq nft set"));
153 o
.default = "dnsmasq.nftset";
162 o
.value("0", _("Disabled"));
163 o
.value("1", _("Enabled"));
168 "supported_interface",
169 _("Supported Interfaces"),
171 "Allows to specify the list of interface names (in lower case) to be explicitly supported by the service. " +
172 "Can be useful if your OpenVPN tunnels have dev option other than tun* or tap*."
181 _("Ignored Interfaces"),
183 "Allows to specify the list of interface names (in lower case) to be ignored by the service. " +
184 "Can be useful if running both VPN server and VPN client on the router."
192 "rule_create_option",
193 _("Rule Create option"),
194 _("Select Add for -A/add and Insert for -I/Insert.")
196 o
.value("add", _("Add"));
197 o
.value("insert", _("Insert"));
204 _("Default ICMP Interface"),
205 _("Force the ICMP protocol interface.")
207 o
.value("", _("No Change"));
208 reply
.interfaces
.forEach((element
) => {
209 if (element
.toLowerCase() !== "ignore") {
219 _("WAN Table FW Mark"),
221 "Starting (WAN) FW Mark for marks used by the service. High starting mark is " +
222 "used to avoid conflict with SQM/QoS. Change with caution together with"
225 _("Service FW Mask") +
229 o
.placeholder
= "010000";
230 o
.datatype
= "hexstring";
236 _("Service FW Mask"),
238 "FW Mask used by the service. High mask is used to avoid conflict with SQM/QoS. " +
239 "Change with caution together with"
242 _("WAN Table FW Mark") +
246 o
.placeholder
= "ff0000";
247 o
.datatype
= "hexstring";
252 "webui_show_ignore_target",
253 _("Add Ignore Target"),
255 "Adds 'ignore' to the list of interfaces for policies. See the %sREADME%s for details."
257 '<a href="' + pkg
.URL
+ '#IgnoreTarget" target="_blank">',
261 o
.value("0", _("Disabled"));
262 o
.value("1", _("Enabled"));
269 "webui_supported_protocol",
270 _("Supported Protocols"),
271 _("Display these protocols in protocol column in Web UI.")
280 "Name, interface and at least one other field are required. Multiple local and remote " +
281 "addresses/devices/domains and ports can be space separated. Placeholders below represent just " +
282 "the format/syntax and will not be used if fields are left blank."
290 o
= s
.option(form
.Flag
, "enabled", _("Enabled"));
294 o
= s
.option(form
.Value
, "name", _("Name"));
296 o
= s
.option(form
.Value
, "src_addr", _("Local addresses / devices"));
298 "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network,string)))";
302 o
= s
.option(form
.Value
, "src_port", _("Local ports"));
303 o
.datatype
= "list(neg(or(portrange,port)))";
304 o
.placeholder
= "0-65535";
308 o
= s
.option(form
.Value
, "dest_addr", _("Remote addresses / domains"));
310 "list(neg(or(cidr,host,ipmask,ipaddr,macaddr,network,string)))";
314 o
= s
.option(form
.Value
, "dest_port", _("Remote ports"));
315 o
.datatype
= "list(neg(or(portrange,port)))";
316 o
.placeholder
= "0-65535";
320 o
= s
.option(form
.ListValue
, "proto", _("Protocol"));
321 var proto
= L
.toArray(
322 L
.uci
.get(pkg
.Name
, "config", "webui_supported_protocol")
325 proto
= ["all", "tcp", "udp", "tcp udp", "icmp"];
327 proto
.forEach((element
) => {
328 if (element
=== "all") {
329 o
.value("", _("all"));
332 o
.value(element
.toLowerCase());
337 o
= s
.option(form
.ListValue
, "chain", _("Chain"));
338 o
.value("", "prerouting");
339 o
.value("forward", "forward");
340 o
.value("input", "input");
341 o
.value("output", "output");
342 o
.value("postrouting", "postrouting");
346 o
= s
.option(form
.ListValue
, "interface", _("Interface"));
347 reply
.interfaces
.forEach((element
) => {
350 o
.datatype
= "network";
359 "Set DSCP tags (in range between 1 and 63) for specific interfaces. See the %sREADME%s for details."
361 '<a href="' + pkg
.URL
+ "#DSCPTag-BasedPolicies" + '" target="_blank">',
365 reply
.interfaces
.forEach((element
) => {
366 if (element
.toLowerCase() !== "ignore") {
370 element
.toUpperCase() + " " + _("DSCP Tag")
372 o
.datatype
= "and(uinteger, min(1), max(63))";
379 _("Custom User File Includes"),
381 "Run the following user files after setting up but before restarting DNSMASQ. " +
382 "See the %sREADME%s for details."
384 '<a href="' + pkg
.URL
+ '#CustomUserFiles" target="_blank">',
392 o
= s
.option(form
.Flag
, "enabled", _("Enabled"));
397 o
= s
.option(form
.Value
, "path", _("Path"));
402 return Promise
.all([status
.render(), m
.render()]);