summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-mwan3
diff options
context:
space:
mode:
Diffstat (limited to 'applications/luci-app-mwan3')
-rw-r--r--applications/luci-app-mwan3/Makefile19
-rw-r--r--applications/luci-app-mwan3/luasrc/controller/mwan3.lua314
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/globalsconfig.lua31
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua240
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua230
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/member.lua44
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/memberconfig.lua31
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/notify.lua45
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua87
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/policyconfig.lua30
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua104
-rw-r--r--applications/luci-app-mwan3/luasrc/model/cbi/mwan/ruleconfig.lua63
-rw-r--r--applications/luci-app-mwan3/luasrc/view/admin_status/index/mwan.htm3
-rw-r--r--applications/luci-app-mwan3/luasrc/view/mwan/overview_status_interface.htm75
-rw-r--r--applications/luci-app-mwan3/luasrc/view/mwan/status_detail.htm39
-rw-r--r--applications/luci-app-mwan3/luasrc/view/mwan/status_diagnostics.htm90
-rw-r--r--applications/luci-app-mwan3/luasrc/view/mwan/status_interface.htm20
-rw-r--r--applications/luci-app-mwan3/luasrc/view/mwan/status_troubleshooting.htm39
-rw-r--r--applications/luci-app-mwan3/po/ja/mwan3.po539
-rw-r--r--applications/luci-app-mwan3/po/ru/mwan3.po568
-rw-r--r--applications/luci-app-mwan3/po/templates/mwan3.pot454
-rw-r--r--applications/luci-app-mwan3/po/zh-cn/mwan3.po769
-rw-r--r--applications/luci-app-mwan3/po/zh-tw/mwan3.po756
-rwxr-xr-xapplications/luci-app-mwan3/root/etc/uci-defaults/60_luci-mwan321
24 files changed, 4611 insertions, 0 deletions
diff --git a/applications/luci-app-mwan3/Makefile b/applications/luci-app-mwan3/Makefile
new file mode 100644
index 0000000000..c719cb134c
--- /dev/null
+++ b/applications/luci-app-mwan3/Makefile
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2017 Dan Luedtke <mail@danrl.com>
+#
+# This is free software, licensed under the Apache License, Version 2.0 .
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=LuCI support for the MWAN3 multiwan hotplug script
+LUCI_DEPENDS:=+mwan3 +libuci-lua +luci-mod-admin-full +luci-app-firewall +luci-lib-nixio
+LUCI_PKGARCH:=all
+PKG_LICENSE:=GPLv2
+
+PKG_MAINTAINER:=Aedan Renner <chipdankly@gmail.com> \
+ Florian Eckert <fe@dev.tdt.de>
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-mwan3/luasrc/controller/mwan3.lua b/applications/luci-app-mwan3/luasrc/controller/mwan3.lua
new file mode 100644
index 0000000000..2d46953e55
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/controller/mwan3.lua
@@ -0,0 +1,314 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+module("luci.controller.mwan3", package.seeall)
+
+sys = require "luci.sys"
+ut = require "luci.util"
+
+ip = "ip -4 "
+
+function index()
+ if not nixio.fs.access("/etc/config/mwan3") then
+ return
+ end
+
+ entry({"admin", "status", "mwan"},
+ alias("admin", "status", "mwan", "overview"),
+ _("Load Balancing"), 600)
+
+ entry({"admin", "status", "mwan", "overview"},
+ template("mwan/status_interface"))
+ entry({"admin", "status", "mwan", "detail"},
+ template("mwan/status_detail"))
+ entry({"admin", "status", "mwan", "diagnostics"},
+ template("mwan/status_diagnostics"))
+ entry({"admin", "status", "mwan", "troubleshooting"},
+ template("mwan/status_troubleshooting"))
+ entry({"admin", "status", "mwan", "interface_status"},
+ call("mwan_Status"))
+ entry({"admin", "status", "mwan", "detailed_status"},
+ call("detailedStatus"))
+ entry({"admin", "status", "mwan", "diagnostics_display"},
+ call("diagnosticsData"), nil).leaf = true
+ entry({"admin", "status", "mwan", "troubleshooting_display"},
+ call("troubleshootingData"))
+
+
+ entry({"admin", "network", "mwan"},
+ alias("admin", "network", "mwan", "interface"),
+ _("Load Balancing"), 600)
+
+ entry({"admin", "network", "mwan", "globals"},
+ cbi("mwan/globalsconfig"),
+ _("Globals"), 5).leaf = true
+ entry({"admin", "network", "mwan", "interface"},
+ arcombine(cbi("mwan/interface"), cbi("mwan/interfaceconfig")),
+ _("Interfaces"), 10).leaf = true
+ entry({"admin", "network", "mwan", "member"},
+ arcombine(cbi("mwan/member"), cbi("mwan/memberconfig")),
+ _("Members"), 20).leaf = true
+ entry({"admin", "network", "mwan", "policy"},
+ arcombine(cbi("mwan/policy"), cbi("mwan/policyconfig")),
+ _("Policies"), 30).leaf = true
+ entry({"admin", "network", "mwan", "rule"},
+ arcombine(cbi("mwan/rule"), cbi("mwan/ruleconfig")),
+ _("Rules"), 40).leaf = true
+ entry({"admin", "network", "mwan", "notify"},
+ form("mwan/notify"),
+ _("Notification"), 50).leaf = true
+end
+
+function mwan_Status()
+ local status = ut.ubus("mwan3", "status", {})
+
+ luci.http.prepare_content("application/json")
+ if status ~= nil then
+ luci.http.write_json(status)
+ else
+ luci.http.write_json({})
+ end
+end
+
+function detailedStatus()
+ local statusInfo = ut.trim(sys.exec("/usr/sbin/mwan3 status"))
+ luci.http.prepare_content("text/plain")
+ if statusInfo ~= "" then
+ luci.http.write(statusInfo)
+ else
+ luci.http.write("Unable to get status information")
+ end
+end
+
+function diagnosticsData(interface, task)
+ function getInterfaceNumber(interface)
+ local number = 0
+ local interfaceNumber
+ local uci = require "luci.model.uci".cursor()
+ uci:foreach("mwan3", "interface",
+ function (section)
+ number = number+1
+ if section[".name"] == interface then
+ interfaceNumber = number
+ end
+ end
+ )
+ return interfaceNumber
+ end
+
+ function diag_command(cmd, device, addr)
+ if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
+ local util = io.popen(cmd %{ut.shellquote(device), ut.shellquote(addr)})
+ if util then
+ while true do
+ local ln = util:read("*l")
+ if not ln then break end
+ luci.http.write(ln)
+ luci.http.write("\n")
+ end
+ util:close()
+ end
+ return
+ end
+ end
+
+ function get_gateway(inteface)
+ local gateway = nil
+ local dump = nil
+
+ dump = require("luci.util").ubus("network.interface.%s_4" % interface, "status", {})
+ if not dump then
+ dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
+ end
+
+ if dump and dump.route then
+ local _, route
+ for _, route in ipairs(dump.route) do
+ if dump.route[_].target == "0.0.0.0" then
+ gateway = dump.route[_].nexthop
+ end
+ end
+ end
+ return gateway
+ end
+
+ local mArray = {}
+ local results = ""
+ local number = getInterfaceNumber(interface)
+
+ local uci = require "luci.model.uci".cursor(nil, "/var/state")
+ local nw = require "luci.model.network".init()
+ local network = nw:get_network(interface)
+ local device = network and network:ifname()
+
+ luci.http.prepare_content("text/plain")
+ if device then
+ if task == "ping_gateway" then
+ local gateway = get_gateway(interface)
+ if gateway ~= nil then
+ diag_command("ping -I %s -c 5 -W 1 %s 2>&1", device, gateway)
+ else
+ luci.http.prepare_content("text/plain")
+ luci.http.write(string.format("No gateway for interface %s found.", interface))
+ end
+ elseif task == "ping_trackips" then
+ local trackips = uci:get("mwan3", interface, "track_ip")
+ if #trackips > 0 then
+ for i in pairs(trackips) do
+ diag_command("ping -I %s -c 5 -W 1 %s 2>&1", device, trackips[i])
+ end
+ else
+ luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
+ end
+ elseif task == "check_rules" then
+ local number = getInterfaceNumber(interface)
+ local iif = 1000 + number
+ local fwmark = 2000 + number
+ local iif_rule = sys.exec(string.format("ip rule | grep %d", iif))
+ local fwmark_rule = sys.exec(string.format("ip rule | grep %d", fwmark))
+ if iif_rule ~= "" and fwmark_rule ~= "" then
+ luci.http.write(string.format("All required IP rules for interface %s found", interface))
+ luci.http.write("\n")
+ luci.http.write(fwmark_rule)
+ luci.http.write(iif_rule)
+ elseif iif_rule == "" and fwmark_rule ~= "" then
+ luci.http.write(string.format("Only one IP rules for interface %s found", interface))
+ luci.http.write("\n")
+ luci.http.write(fwmark_rule)
+ elseif iif_rule ~= "" and fwmark_rule == "" then
+ luci.http.write(string.format("Only one IP rules for interface %s found", interface))
+ luci.http.write("\n")
+ luci.http.write(iif_rule)
+ else
+ luci.http.write(string.format("Missing both IP rules for interface %s", interface))
+ end
+ elseif task == "check_routes" then
+ local number = getInterfaceNumber(interface)
+ local routeTable = sys.exec(string.format("ip route list table %s", number))
+ if routeTable ~= "" then
+ luci.http.write(string.format("Routing table %s for interface %s found", number, interface))
+ luci.http.write("\n")
+ luci.http.write(routeTable)
+ else
+ luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
+ end
+ elseif task == "hotplug_ifup" then
+ os.execute(string.format("/usr/sbin/mwan3 ifup %s", ut.shellquote(interface)))
+ luci.http.write(string.format("Hotplug ifup sent to interface %s", interface))
+ elseif task == "hotplug_ifdown" then
+ os.execute(string.format("/usr/sbin/mwan3 ifdown %s", ut.shellquote(interface)))
+ luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface))
+ else
+ luci.http.write("Unknown task")
+ end
+ else
+ luci.http.write(string.format("Unable to perform diagnostic tests on %s.", interface))
+ luci.http.write("\n")
+ luci.http.write("There is no physical or virtual device associated with this interface.")
+ end
+end
+
+function troubleshootingData()
+ local ver = require "luci.version"
+ local dash = "-------------------------------------------------"
+
+ luci.http.prepare_content("text/plain")
+
+ luci.http.write("\n")
+ luci.http.write("\n")
+ luci.http.write("Software-Version")
+ luci.http.write("\n")
+ luci.http.write(dash)
+ luci.http.write("\n")
+ if ver.distversion then
+ luci.http.write(string.format("OpenWrt - %s", ver.distversion))
+ luci.http.write("\n")
+ else
+ luci.http.write("OpenWrt - unknown")
+ luci.http.write("\n")
+ end
+
+ if ver.luciversion then
+ luci.http.write(string.format("LuCI - %s", ver.luciversion))
+ luci.http.write("\n")
+ else
+ luci.http.write("LuCI - unknown")
+ luci.http.write("\n")
+ end
+
+ luci.http.write("\n")
+ luci.http.write("\n")
+ local output = ut.trim(sys.exec("ip a show"))
+ luci.http.write("Output of \"ip a show\"")
+ luci.http.write("\n")
+ luci.http.write(dash)
+ luci.http.write("\n")
+ if output ~= "" then
+ luci.http.write(output)
+ luci.http.write("\n")
+ else
+ luci.http.write("No data found")
+ luci.http.write("\n")
+ end
+
+ luci.http.write("\n")
+ luci.http.write("\n")
+ local output = ut.trim(sys.exec("ip route show"))
+ luci.http.write("Output of \"ip route show\"")
+ luci.http.write("\n")
+ luci.http.write(dash)
+ luci.http.write("\n")
+ if output ~= "" then
+ luci.http.write(output)
+ luci.http.write("\n")
+ else
+ luci.http.write("No data found")
+ luci.http.write("\n")
+ end
+
+ luci.http.write("\n")
+ luci.http.write("\n")
+ local output = ut.trim(sys.exec("ip rule show"))
+ luci.http.write("Output of \"ip rule show\"")
+ luci.http.write("\n")
+ luci.http.write(dash)
+ luci.http.write("\n")
+ if output ~= "" then
+ luci.http.write(output)
+ luci.http.write("\n")
+ else
+ luci.http.write("No data found")
+ luci.http.write("\n")
+ end
+
+ luci.http.write("\n")
+ luci.http.write("\n")
+ luci.http.write("Output of \"ip route list table 1-250\"")
+ luci.http.write("\n")
+ luci.http.write(dash)
+ luci.http.write("\n")
+ for i=1,250 do
+ local output = ut.trim(sys.exec(string.format("ip route list table %d", i)))
+ if output ~= "" then
+ luci.http.write(string.format("Table %s: ", i))
+ luci.http.write(output)
+ luci.http.write("\n")
+ end
+ end
+
+ luci.http.write("\n")
+ luci.http.write("\n")
+ local output = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
+ luci.http.write("Output of \"iptables -L -t mangle -v -n\"")
+ luci.http.write("\n")
+ luci.http.write(dash)
+ luci.http.write("\n")
+ if output ~= "" then
+ luci.http.write(output)
+ luci.http.write("\n")
+ else
+ luci.http.write("No data found")
+ luci.http.write("\n")
+ end
+end
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/globalsconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/globalsconfig.lua
new file mode 100644
index 0000000000..d8f90e1e25
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/globalsconfig.lua
@@ -0,0 +1,31 @@
+-- Copyright 2017 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+local net = require "luci.model.network".init()
+
+
+m = Map("mwan3", translate("MWAN - Globals"))
+
+s = m:section(NamedSection, "globals", "globals", nil)
+n = s:option(ListValue, "local_source",
+ translate("Local source interface"),
+ translate("Use the IP address of this interface as source IP " ..
+ "address for traffic initiated by the router itself"))
+n:value("none")
+n.default = "none"
+for _, net in ipairs(net:get_networks()) do
+ if net:name() ~= "loopback" then
+ n:value(net:name())
+ end
+end
+n.rmempty = false
+
+mask = s:option(
+ Value,
+ "mmx_mask",
+ translate("Firewall mask"),
+ translate("Enter value in hex, starting with <code>0x</code>"))
+mask.datatype = "hex(4)"
+mask.default = "0xff00"
+
+return m
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua
new file mode 100644
index 0000000000..162b388d17
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua
@@ -0,0 +1,240 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+uci = require "uci"
+
+
+function interfaceWarnings(overview, count, iface_max)
+ local warnings = ""
+ if count <= iface_max then
+ warnings = string.format("<strong>%s</strong><br />",
+ translatef("There are currently %d of %d supported interfaces configured", count, iface_max)
+ )
+ else
+ warnings = string.format("<strong>%s</strong><br />",
+ translatef("WARNING: %d interfaces are configured exceeding the maximum of %d!", count, iface_max)
+ )
+ end
+
+ for i, k in pairs(overview) do
+ if overview[i]["network"] == false then
+ warnings = warnings .. string.format("<strong>%s</strong><br />",
+ translatef("WARNING: Interface %s are not found in /etc/config/network", i)
+ )
+ end
+
+ if overview[i]["default_route"] == false then
+ warnings = warnings .. string.format("<strong>%s</strong><br />",
+ translatef("WARNING: Interface %s has no default route in the main routing table", i)
+ )
+ end
+
+ if overview[i]["reliability"] == false then
+ warnings = warnings .. string.format("<strong>%s</strong><br />",
+ translatef("WARNING: Interface %s has a higher reliability " ..
+ "requirement than tracking hosts (%d)", i, overview[i]["tracking"])
+ )
+ end
+
+ if overview[i]["duplicate_metric"] == true then
+ warnings = warnings .. string.format("<strong>%s</strong><br />",
+ translatef("WARNING: Interface %s has a duplicate metric %s configured", i, overview[i]["metric"])
+ )
+ end
+ end
+
+ return warnings
+end
+
+function configCheck()
+ local overview = {}
+ local count = 0
+ local duplicate_metric = {}
+ uci.cursor():foreach("mwan3", "interface",
+ function (section)
+ local uci = uci.cursor(nil, "/var/state")
+ local iface = section[".name"]
+ overview[iface] = {}
+ count = count + 1
+ local network = uci:get("network", iface)
+ overview[iface]["network"] = false
+ if network ~= nil then
+ overview[iface]["network"] = true
+
+ local device = uci:get("network", iface, "ifname")
+ if device ~= nil then
+ overview[iface]["device"] = device
+ end
+
+ local metric = uci:get("network", iface, "metric")
+ if metric ~= nil then
+ overview[iface]["metric"] = metric
+ overview[iface]["duplicate_metric"] = false
+ for _, m in ipairs(duplicate_metric) do
+ if m == metric then
+ overview[iface]["duplicate_metric"] = true
+ end
+ end
+ table.insert(duplicate_metric, metric)
+ end
+
+ local dump = require("luci.util").ubus("network.interface.%s" % iface, "status", {})
+ overview[iface]["default_route"] = false
+ if dump and dump.route then
+ local _, route
+ for _, route in ipairs(dump.route) do
+ if dump.route[_].target == "0.0.0.0" then
+ overview[iface]["default_route"] = true
+ end
+ end
+ end
+ end
+
+ local trackingNumber = uci:get("mwan3", iface, "track_ip")
+ overview[iface]["tracking"] = 0
+ if trackingNumber and #trackingNumber > 0 then
+ overview[iface]["tracking"] = #trackingNumber
+ overview[iface]["reliability"] = false
+ local reliabilityNumber = tonumber(uci:get("mwan3", iface, "reliability"))
+ if reliabilityNumber and reliabilityNumber <= #trackingNumber then
+ overview[iface]["reliability"] = true
+ end
+ end
+ end
+ )
+
+ -- calculate iface_max usage from firewall mmx_mask
+ function bit(p)
+ return 2 ^ (p - 1)
+ end
+ function hasbit(x, p)
+ return x % (p + p) >= p
+ end
+ function setbit(x, p)
+ return hasbit(x, p) and x or x + p
+ end
+
+ local uci = require("uci").cursor(nil, "/var/state")
+ local mmx_mask = uci:get("mwan3", "globals", "mmx_mask") or "0x3F00"
+ local number = tonumber(mmx_mask, 16)
+ local bits = 0
+ local iface_max = 0
+ for i=1,16 do
+ if hasbit(number, bit(i)) then
+ bits = bits + 1
+ iface_max = setbit( iface_max, bit(bits))
+ end
+ end
+
+ -- subtract blackhole, unreachable and default table from iface_max
+ iface_max = iface_max - 3
+
+ return overview, count, iface_max
+end
+
+m5 = Map("mwan3", translate("MWAN - Interfaces"),
+ interfaceWarnings(configCheck()))
+
+mwan_interface = m5:section(TypedSection, "interface", nil,
+ translate("MWAN supports up to 252 physical and/or logical interfaces<br />" ..
+ "MWAN requires that all interfaces have a unique metric configured in /etc/config/network<br />" ..
+ "Names must match the interface name found in /etc/config/network<br />" ..
+ "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" ..
+ "Interfaces may not share the same name as configured members, policies or rules"))
+mwan_interface.addremove = true
+mwan_interface.dynamic = false
+mwan_interface.sectionhead = translate("Interface")
+mwan_interface.sortable = false
+mwan_interface.template = "cbi/tblsection"
+mwan_interface.extedit = dsp.build_url("admin", "network", "mwan", "interface", "%s")
+function mwan_interface.create(self, section)
+ TypedSection.create(self, section)
+ m5.uci:save("mwan3")
+ luci.http.redirect(dsp.build_url("admin", "network", "mwan", "interface", section))
+end
+
+enabled = mwan_interface:option(DummyValue, "enabled", translate("Enabled"))
+enabled.rawhtml = true
+function enabled.cfgvalue(self, s)
+ if self.map:get(s, "enabled") == "1" then
+ return translate("Yes")
+ else
+ return translate("No")
+ end
+end
+
+track_method = mwan_interface:option(DummyValue, "track_method", translate("Tracking method"))
+track_method.rawhtml = true
+function track_method.cfgvalue(self, s)
+ local tracked = self.map:get(s, "track_ip")
+ if tracked then
+ return self.map:get(s, "track_method") or "ping"
+ else
+ return "&#8212;"
+ end
+end
+
+reliability = mwan_interface:option(DummyValue, "reliability", translate("Tracking reliability"))
+reliability.rawhtml = true
+function reliability.cfgvalue(self, s)
+ local tracked = self.map:get(s, "track_ip")
+ if tracked then
+ return self.map:get(s, "reliability") or "1"
+ else
+ return "&#8212;"
+ end
+end
+
+interval = mwan_interface:option(DummyValue, "interval", translate("Ping interval"))
+interval.rawhtml = true
+function interval.cfgvalue(self, s)
+ local tracked = self.map:get(s, "track_ip")
+ if tracked then
+ local intervalValue = self.map:get(s, "interval")
+ if intervalValue then
+ return intervalValue .. "s"
+ else
+ return "5s"
+ end
+ else
+ return "&#8212;"
+ end
+end
+
+down = mwan_interface:option(DummyValue, "down", translate("Interface down"))
+down.rawhtml = true
+function down.cfgvalue(self, s)
+ local tracked = self.map:get(s, "track_ip")
+ if tracked then
+ return self.map:get(s, "down") or "3"
+ else
+ return "&#8212;"
+ end
+end
+
+up = mwan_interface:option(DummyValue, "up", translate("Interface up"))
+up.rawhtml = true
+function up.cfgvalue(self, s)
+ local tracked = self.map:get(s, "track_ip")
+ if tracked then
+ return self.map:get(s, "up") or "3"
+ else
+ return "&#8212;"
+ end
+end
+
+metric = mwan_interface:option(DummyValue, "metric", translate("Metric"))
+metric.rawhtml = true
+function metric.cfgvalue(self, s)
+ local uci = uci.cursor(nil, "/var/state")
+ local metric = uci:get("network", s, "metric")
+ if metric then
+ return metric
+ else
+ return "&#8212;"
+ end
+end
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua
new file mode 100644
index 0000000000..a6570e341c
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/interfaceconfig.lua
@@ -0,0 +1,230 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+arg[1] = arg[1] or ""
+
+
+m5 = Map("mwan3", translatef("MWAN Interface Configuration - %s", arg[1]))
+ m5.redirect = dsp.build_url("admin", "network", "mwan", "interface")
+
+mwan_interface = m5:section(NamedSection, arg[1], "interface", "")
+mwan_interface.addremove = false
+mwan_interface.dynamic = false
+
+enabled = mwan_interface:option(ListValue, "enabled", translate("Enabled"))
+enabled.default = "1"
+enabled:value("1", translate("Yes"))
+enabled:value("0", translate("No"))
+
+initial_state = mwan_interface:option(ListValue, "initial_state", translate("Initial state"),
+ translate("Expect interface state on up event"))
+initial_state.default = "online"
+initial_state:value("online", translate("Online"))
+initial_state:value("offline", translate("Offline"))
+
+family = mwan_interface:option(ListValue, "family", translate("Internet Protocol"))
+family.default = "ipv4"
+family:value("ipv4", translate("IPv4"))
+family:value("ipv6", translate("IPv6"))
+
+track_ip = mwan_interface:option(DynamicList, "track_ip", translate("Tracking hostname or IP address"),
+ translate("This hostname or IP address will be pinged to determine if the link is up or down. Leave blank to assume interface is always online"))
+track_ip.datatype = "host"
+
+track_method = mwan_interface:option(ListValue, "track_method", translate("Tracking method"))
+track_method.default = "ping"
+track_method:value("ping")
+track_method:value("arping")
+track_method:value("httping")
+
+reliability = mwan_interface:option(Value, "reliability", translate("Tracking reliability"),
+ translate("Acceptable values: 1-100. This many Tracking IP addresses must respond for the link to be deemed up"))
+reliability.datatype = "range(1, 100)"
+reliability.default = "1"
+
+count = mwan_interface:option(ListValue, "count", translate("Ping count"))
+count.default = "1"
+count:value("1")
+count:value("2")
+count:value("3")
+count:value("4")
+count:value("5")
+
+size = mwan_interface:option(Value, "size", translate("Ping size"))
+size.default = "56"
+size:depends("track_method", "ping")
+size:value("8")
+size:value("24")
+size:value("56")
+size:value("120")
+size:value("248")
+size:value("504")
+size:value("1016")
+size:value("1472")
+size:value("2040")
+size.datatype = "range(1, 65507)"
+size.rmempty = false
+size.optional = false
+
+check_quality = mwan_interface:option(Flag, "check_quality", translate("Check link quality"))
+check_quality:depends("track_method", "ping")
+check_quality.default = false
+
+failure_latency = mwan_interface:option(Value, "failure_latency", translate("Max packet latency [ms]"))
+failure_latency:depends("check_quality", 1)
+failure_latency.default = "1000"
+failure_latency:value("25")
+failure_latency:value("50")
+failure_latency:value("75")
+failure_latency:value("100")
+failure_latency:value("150")
+failure_latency:value("200")
+failure_latency:value("250")
+failure_latency:value("300")
+
+failure_loss = mwan_interface:option(Value, "failure_loss", translate("Max packet loss [%]"))
+failure_loss:depends("check_quality", 1)
+failure_loss.default = "20"
+failure_loss:value("2")
+failure_loss:value("5")
+failure_loss:value("10")
+failure_loss:value("20")
+failure_loss:value("25")
+
+recovery_latency = mwan_interface:option(Value, "recovery_latency", translate("Min packet latency [ms]"))
+recovery_latency:depends("check_quality", 1)
+recovery_latency.default = "500"
+recovery_latency:value("25")
+recovery_latency:value("50")
+recovery_latency:value("75")
+recovery_latency:value("100")
+recovery_latency:value("150")
+recovery_latency:value("200")
+recovery_latency:value("250")
+recovery_latency:value("300")
+
+recovery_loss = mwan_interface:option(Value, "recovery_loss", translate("Min packet loss [%]"))
+recovery_loss:depends("check_quality", 1)
+recovery_loss.default = "5"
+recovery_loss:value("2")
+recovery_loss:value("5")
+recovery_loss:value("10")
+recovery_loss:value("20")
+recovery_loss:value("25")
+
+timeout = mwan_interface:option(ListValue, "timeout", translate("Ping timeout"))
+timeout.default = "2"
+timeout:value("1", translatef("%d second", 1))
+timeout:value("2", translatef("%d seconds", 2))
+timeout:value("3", translatef("%d seconds", 3))
+timeout:value("4", translatef("%d seconds", 4))
+timeout:value("5", translatef("%d seconds", 5))
+timeout:value("6", translatef("%d seconds", 6))
+timeout:value("7", translatef("%d seconds", 7))
+timeout:value("8", translatef("%d seconds", 8))
+timeout:value("9", translatef("%d seconds", 9))
+timeout:value("10", translatef("%d seconds", 10))
+
+interval = mwan_interface:option(ListValue, "interval", translate("Ping interval"))
+interval.default = "5"
+interval:value("1", translatef("%d second", 1))
+interval:value("3", translatef("%d seconds", 3))
+interval:value("5", translatef("%d seconds", 5))
+interval:value("10", translatef("%d seconds", 10))
+interval:value("20", translatef("%d seconds", 20))
+interval:value("30", translatef("%d seconds", 30))
+interval:value("60", translatef("%d minute", 1))
+interval:value("300", translatef("%d minutes", 5))
+interval:value("600", translatef("%d minutes", 10))
+interval:value("900", translatef("%d minutes", 15))
+interval:value("1800", translatef("%d minutes", 30))
+interval:value("3600", translatef("%d hour", 1))
+
+failure = mwan_interface:option(Value, "failure_interval", translate("Failure interval"),
+ translate("Ping interval during failure detection"))
+failure.default = "5"
+failure:value("1", translatef("%d second", 1))
+failure:value("3", translatef("%d seconds", 3))
+failure:value("5", translatef("%d seconds", 5))
+failure:value("10", translatef("%d seconds", 10))
+failure:value("20", translatef("%d seconds", 20))
+failure:value("30", translatef("%d seconds", 30))
+failure:value("60", translatef("%d minute", 1))
+failure:value("300", translatef("%d minutes", 5))
+failure:value("600", translatef("%d minutes", 10))
+failure:value("900", translatef("%d minutes", 15))
+failure:value("1800", translatef("%d minutes", 30))
+failure:value("3600", translatef("%d hour", 1))
+
+keep_failure = mwan_interface:option(Flag, "keep_failure_interval", translate("Keep failure interval"),
+ translate("Keep ping failure interval during failure state"))
+keep_failure.default = keep_failure.disabled
+
+recovery = mwan_interface:option(Value, "recovery_interval", translate("Recovery interval"),
+ translate("Ping interval during failure recovering"))
+recovery.default = "5"
+recovery:value("1", translatef("%d second", 1))
+recovery:value("3", translatef("%d seconds", 3))
+recovery:value("5", translatef("%d seconds", 5))
+recovery:value("10", translatef("%d seconds", 10))
+recovery:value("20", translatef("%d seconds", 20))
+recovery:value("30", translatef("%d seconds", 30))
+recovery:value("60", translatef("%d minute", 1))
+recovery:value("300", translatef("%d minutes", 5))
+recovery:value("600", translatef("%d minutes", 10))
+recovery:value("900", translatef("%d minutes", 15))
+recovery:value("1800", translatef("%d minutes", 30))
+recovery:value("3600", translatef("%d hour", 1))
+
+down = mwan_interface:option(ListValue, "down", translate("Interface down"),
+ translate("Interface will be deemed down after this many failed ping tests"))
+down.default = "3"
+down:value("1")
+down:value("2")
+down:value("3")
+down:value("4")
+down:value("5")
+down:value("6")
+down:value("7")
+down:value("8")
+down:value("9")
+down:value("10")
+
+up = mwan_interface:option(ListValue, "up", translate("Interface up"),
+ translate("Downed interface will be deemed up after this many successful ping tests"))
+up.default = "3"
+up:value("1")
+up:value("2")
+up:value("3")
+up:value("4")
+up:value("5")
+up:value("6")
+up:value("7")
+up:value("8")
+up:value("9")
+up:value("10")
+
+flush = mwan_interface:option(ListValue, "flush_conntrack", translate("Flush conntrack table"),
+ translate("Flush global firewall conntrack table on interface events"))
+flush.default = "never"
+flush:value("ifup", translate("ifup"))
+flush:value("ifdown", translate("ifdown"))
+flush:value("never", translate("never"))
+flush:value("always", translate("always"))
+
+metric = mwan_interface:option(DummyValue, "metric", translate("Metric"),
+ translate("This displays the metric assigned to this interface in /etc/config/network"))
+metric.rawhtml = true
+function metric.cfgvalue(self, s)
+ local uci = require "luci.model.uci".cursor(nil, "/var/state")
+ local metric = uci:get("network", arg[1], "metric")
+ if metric then
+ return metric
+ else
+ return "&#8212;"
+ end
+end
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/member.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/member.lua
new file mode 100644
index 0000000000..9b4ab102d5
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/member.lua
@@ -0,0 +1,44 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+
+
+m5 = Map("mwan3", translate("MWAN - Members"))
+
+mwan_member = m5:section(TypedSection, "member", nil,
+ translate("Members are profiles attaching a metric and weight to an MWAN interface<br />" ..
+ "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" ..
+ "Members may not share the same name as configured interfaces, policies or rules"))
+mwan_member.addremove = true
+mwan_member.dynamic = false
+mwan_member.sectionhead = translate("Member")
+mwan_member.sortable = true
+mwan_member.template = "cbi/tblsection"
+mwan_member.extedit = dsp.build_url("admin", "network", "mwan", "member", "%s")
+function mwan_member.create(self, section)
+ TypedSection.create(self, section)
+ m5.uci:save("mwan3")
+ luci.http.redirect(dsp.build_url("admin", "network", "mwan", "member", section))
+end
+
+interface = mwan_member:option(DummyValue, "interface", translate("Interface"))
+interface.rawhtml = true
+function interface.cfgvalue(self, s)
+ return self.map:get(s, "interface") or "&#8212;"
+end
+
+metric = mwan_member:option(DummyValue, "metric", translate("Metric"))
+metric.rawhtml = true
+function metric.cfgvalue(self, s)
+ return self.map:get(s, "metric") or "1"
+end
+
+weight = mwan_member:option(DummyValue, "weight", translate("Weight"))
+weight.rawhtml = true
+function weight.cfgvalue(self, s)
+ return self.map:get(s, "weight") or "1"
+end
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/memberconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/memberconfig.lua
new file mode 100644
index 0000000000..27d9a3e858
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/memberconfig.lua
@@ -0,0 +1,31 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+arg[1] = arg[1] or ""
+
+
+m5 = Map("mwan3", translatef("MWAN Member Configuration - %s", arg[1]))
+m5.redirect = dsp.build_url("admin", "network", "mwan", "member")
+
+mwan_member = m5:section(NamedSection, arg[1], "member", "")
+mwan_member.addremove = false
+mwan_member.dynamic = false
+
+interface = mwan_member:option(Value, "interface", translate("Interface"))
+m5.uci:foreach("mwan3", "interface",
+ function(s)
+ interface:value(s['.name'], s['.name'])
+ end
+)
+
+metric = mwan_member:option(Value, "metric", translate("Metric"),
+ translate("Acceptable values: 1-256. Defaults to 1 if not set"))
+metric.datatype = "range(1, 256)"
+
+weight = mwan_member:option(Value, "weight", translate("Weight"),
+ translate("Acceptable values: 1-1000. Defaults to 1 if not set"))
+weight.datatype = "range(1, 1000)"
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/notify.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/notify.lua
new file mode 100644
index 0000000000..4c6e21003e
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/notify.lua
@@ -0,0 +1,45 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+local fs = require "nixio.fs"
+local ut = require "luci.util"
+script = "/etc/mwan3.user"
+
+
+m5 = SimpleForm("luci", translate("MWAN - Notification"))
+
+f = m5:section(SimpleSection, nil,
+ translate("This section allows you to modify the content of \"/etc/mwan3.user\".<br />" ..
+ "The file is also preserved during sysupgrade.<br />" ..
+ "<br />" ..
+ "Notes:<br />" ..
+ "This file is interpreted as a shell script.<br />" ..
+ "The first line of the script must be &#34;#!/bin/sh&#34; without quotes.<br />" ..
+ "Lines beginning with # are comments and are not executed.<br />" ..
+ "Put your custom mwan3 action here, they will<br />" ..
+ "be executed with each netifd hotplug interface event<br />" ..
+ "on interfaces for which mwan3 is enabled.<br />" ..
+ "<br />" ..
+ "There are three main environment variables that are passed to this script.<br />" ..
+ "<br />" ..
+ "$ACTION <br />" ..
+ "* \"ifup\" Is called by netifd and mwan3track <br />" ..
+ "* \"ifdown\" Is called by netifd and mwan3track <br />" ..
+ "* \"connected\" Is only called by mwan3track if tracking was successful <br />" ..
+ "* \"disconnected\" Is only called by mwan3track if tracking has failed <br />" ..
+ "$INTERFACE Name of the interface which went up or down (e.g. \"wan\" or \"wwan\")<br />" ..
+ "$DEVICE Physical device name which interface went up or down (e.g. \"eth0\" or \"wwan0\")<br />" ..
+ "<br />"))
+
+t = f:option(TextValue, "lines")
+t.rmempty = true
+t.rows = 20
+function t.cfgvalue()
+ return fs.readfile(script)
+end
+function t.write(self, section, data)
+ return fs.writefile(script, ut.trim(data:gsub("\r\n", "\n")) .. "\n")
+end
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua
new file mode 100644
index 0000000000..4543260f6f
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua
@@ -0,0 +1,87 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+uci = require "uci"
+
+
+function policyCheck()
+ local policy_error = {}
+
+ uci.cursor():foreach("mwan3", "policy",
+ function (section)
+ policy_error[section[".name"]] = false
+ if string.len(section[".name"]) > 15 then
+ policy_error[section[".name"]] = true
+ end
+ end
+ )
+
+ return policy_error
+end
+
+function policyError(policy_error)
+ local warnings = ""
+ for i, k in pairs(policy_error) do
+ if policy_error[i] == true then
+ warnings = warnings .. string.format("<strong>%s</strong><br />",
+ translatef("WARNING: Policy %s has exceeding the maximum name of 15 characters", i)
+ )
+ end
+ end
+
+ return warnings
+end
+
+m5 = Map("mwan3", translate("MWAN - Policies"),
+ policyError(policyCheck()))
+
+mwan_policy = m5:section(TypedSection, "policy", nil,
+ translate("Policies are profiles grouping one or more members controlling how MWAN distributes traffic<br />" ..
+ "Member interfaces with lower metrics are used first<br />" ..
+ "Member interfaces with the same metric will be load-balanced<br />" ..
+ "Load-balanced member interfaces distribute more traffic out those with higher weights<br />" ..
+ "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" ..
+ "Names must be 15 characters or less<br />" ..
+ "Policies may not share the same name as configured interfaces, members or rules"))
+mwan_policy.addremove = true
+mwan_policy.dynamic = false
+mwan_policy.sectionhead = translate("Policy")
+mwan_policy.sortable = true
+mwan_policy.template = "cbi/tblsection"
+mwan_policy.extedit = dsp.build_url("admin", "network", "mwan", "policy", "%s")
+function mwan_policy.create(self, section)
+ TypedSection.create(self, section)
+ m5.uci:save("mwan3")
+ luci.http.redirect(dsp.build_url("admin", "network", "mwan", "policy", section))
+end
+
+use_member = mwan_policy:option(DummyValue, "use_member", translate("Members assigned"))
+use_member.rawhtml = true
+function use_member.cfgvalue(self, s)
+ local memberConfig, memberList = self.map:get(s, "use_member"), ""
+ if memberConfig then
+ for k,v in pairs(memberConfig) do
+ memberList = memberList .. v .. "<br />"
+ end
+ return memberList
+ else
+ return "&#8212;"
+ end
+end
+
+last_resort = mwan_policy:option(DummyValue, "last_resort", translate("Last resort"))
+last_resort.rawhtml = true
+function last_resort.cfgvalue(self, s)
+ local action = self.map:get(s, "last_resort")
+ if action == "blackhole" then
+ return translate("blackhole (drop)")
+ elseif action == "default" then
+ return translate("default (use main routing table)")
+ else
+ return translate("unreachable (reject)")
+ end
+end
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policyconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policyconfig.lua
new file mode 100644
index 0000000000..d1a063d093
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/policyconfig.lua
@@ -0,0 +1,30 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+arg[1] = arg[1] or ""
+
+
+m5 = Map("mwan3", translatef("MWAN Policy Configuration - %s", arg[1]))
+m5.redirect = dsp.build_url("admin", "network", "mwan", "policy")
+
+mwan_policy = m5:section(NamedSection, arg[1], "policy", "")
+mwan_policy.addremove = false
+mwan_policy.dynamic = false
+
+member = mwan_policy:option(DynamicList, "use_member", translate("Member used"))
+m5.uci:foreach("mwan3", "member",
+ function(s)
+ member:value(s['.name'], s['.name'])
+ end
+)
+
+last_resort = mwan_policy:option(ListValue, "last_resort", translate("Last resort"),
+ translate("When all policy members are offline use this behavior for matched traffic"))
+last_resort.default = "unreachable"
+last_resort:value("unreachable", translate("unreachable (reject)"))
+last_resort:value("blackhole", translate("blackhole (drop)"))
+last_resort:value("default", translate("default (use main routing table)"))
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua
new file mode 100644
index 0000000000..f0b94bd0bb
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua
@@ -0,0 +1,104 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+uci = require "uci"
+
+
+function ruleCheck()
+ local rule_error = {}
+ uci.cursor():foreach("mwan3", "rule",
+ function (section)
+ rule_error[section[".name"]] = false
+ local uci = uci.cursor(nil, "/var/state")
+ local sourcePort = uci:get("mwan3", section[".name"], "src_port")
+ local destPort = uci:get("mwan3", section[".name"], "dest_port")
+ if sourcePort ~= nil or destPort ~= nil then
+ local protocol = uci:get("mwan3", section[".name"], "proto")
+ if protocol == nil or protocol == "all" then
+ rule_error[section[".name"]] = true
+ end
+ end
+ end
+ )
+ return rule_error
+end
+
+function ruleWarn(rule_error)
+ local warnings = ""
+ for i, k in pairs(rule_error) do
+ if rule_error[i] == true then
+ warnings = warnings .. string.format("<strong>%s</strong><br />",
+ translatef("WARNING: Rule %s have a port configured with no or improper protocol specified!", i)
+ )
+ end
+ end
+
+ return warnings
+end
+
+m5 = Map("mwan3", translate("MWAN - Rules"),
+ ruleWarn(ruleCheck())
+ )
+
+mwan_rule = m5:section(TypedSection, "rule", nil,
+ translate("Rules specify which traffic will use a particular MWAN policy<br />" ..
+ "Rules are based on IP address, port or protocol<br />" ..
+ "Rules are matched from top to bottom<br />" ..
+ "Rules below a matching rule are ignored<br />" ..
+ "Traffic not matching any rule is routed using the main routing table<br />" ..
+ "Traffic destined for known (other than default) networks is handled by the main routing table<br />" ..
+ "Traffic matching a rule, but all WAN interfaces for that policy are down will be blackholed<br />" ..
+ "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" ..
+ "Rules may not share the same name as configured interfaces, members or policies"))
+mwan_rule.addremove = true
+mwan_rule.anonymous = false
+mwan_rule.dynamic = false
+mwan_rule.sectionhead = translate("Rule")
+mwan_rule.sortable = true
+mwan_rule.template = "cbi/tblsection"
+mwan_rule.extedit = dsp.build_url("admin", "network", "mwan", "rule", "%s")
+function mwan_rule.create(self, section)
+ TypedSection.create(self, section)
+ m5.uci:save("mwan3")
+ luci.http.redirect(dsp.build_url("admin", "network", "mwan", "rule", section))
+end
+
+src_ip = mwan_rule:option(DummyValue, "src_ip", translate("Source address"))
+src_ip.rawhtml = true
+function src_ip.cfgvalue(self, s)
+ return self.map:get(s, "src_ip") or "&#8212;"
+end
+
+src_port = mwan_rule:option(DummyValue, "src_port", translate("Source port"))
+src_port.rawhtml = true
+function src_port.cfgvalue(self, s)
+ return self.map:get(s, "src_port") or "&#8212;"
+end
+
+dest_ip = mwan_rule:option(DummyValue, "dest_ip", translate("Destination address"))
+dest_ip.rawhtml = true
+function dest_ip.cfgvalue(self, s)
+ return self.map:get(s, "dest_ip") or "&#8212;"
+end
+
+dest_port = mwan_rule:option(DummyValue, "dest_port", translate("Destination port"))
+dest_port.rawhtml = true
+function dest_port.cfgvalue(self, s)
+ return self.map:get(s, "dest_port") or "&#8212;"
+end
+
+proto = mwan_rule:option(DummyValue, "proto", translate("Protocol"))
+proto.rawhtml = true
+function proto.cfgvalue(self, s)
+ return self.map:get(s, "proto") or "all"
+end
+
+use_policy = mwan_rule:option(DummyValue, "use_policy", translate("Policy assigned"))
+use_policy.rawhtml = true
+function use_policy.cfgvalue(self, s)
+ return self.map:get(s, "use_policy") or "&#8212;"
+end
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/model/cbi/mwan/ruleconfig.lua b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/ruleconfig.lua
new file mode 100644
index 0000000000..84adfcf910
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/model/cbi/mwan/ruleconfig.lua
@@ -0,0 +1,63 @@
+-- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+-- Licensed to the public under the GNU General Public License v2.
+
+dsp = require "luci.dispatcher"
+arg[1] = arg[1] or ""
+
+
+m5 = Map("mwan3", translatef("MWAN Rule Configuration - %s", arg[1]))
+m5.redirect = dsp.build_url("admin", "network", "mwan", "rule")
+
+mwan_rule = m5:section(NamedSection, arg[1], "rule", "")
+mwan_rule.addremove = false
+mwan_rule.dynamic = false
+
+src_ip = mwan_rule:option(Value, "src_ip", translate("Source address"),
+ translate("Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"))
+src_ip.datatype = ipaddr
+
+src_port = mwan_rule:option(Value, "src_port", translate("Source port"),
+ translate("May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or as a portrange (eg \"1024:2048\") without quotes"))
+
+dest_ip = mwan_rule:option(Value, "dest_ip", translate("Destination address"),
+ translate("Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"))
+dest_ip.datatype = ipaddr
+
+dest_port = mwan_rule:option(Value, "dest_port", translate("Destination port"),
+ translate("May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or as a portrange (eg \"1024:2048\") without quotes"))
+
+proto = mwan_rule:option(Value, "proto", translate("Protocol"),
+ translate("View the content of /etc/protocols for protocol description"))
+proto.default = "all"
+proto.rmempty = false
+proto:value("all")
+proto:value("tcp")
+proto:value("udp")
+proto:value("icmp")
+proto:value("esp")
+
+sticky = mwan_rule:option(ListValue, "sticky", translate("Sticky"),
+ translate("Traffic from the same source IP address that previously matched this rule within the sticky timeout period will use the same WAN interface"))
+sticky.default = "0"
+sticky:value("1", translate("Yes"))
+sticky:value("0", translate("No"))
+
+timeout = mwan_rule:option(Value, "timeout", translate("Sticky timeout"),
+ translate("Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"))
+timeout.datatype = "range(1, 1000000)"
+
+ipset = mwan_rule:option(Value, "ipset", translate("IPset"),
+ translate("Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/youtube.com/youtube\")"))
+
+policy = mwan_rule:option(Value, "use_policy", translate("Policy assigned"))
+m5.uci:foreach("mwan3", "policy",
+ function(s)
+ policy:value(s['.name'], s['.name'])
+ end
+)
+policy:value("unreachable", translate("unreachable (reject)"))
+policy:value("blackhole", translate("blackhole (drop)"))
+policy:value("default", translate("default (use main routing table)"))
+
+return m5
diff --git a/applications/luci-app-mwan3/luasrc/view/admin_status/index/mwan.htm b/applications/luci-app-mwan3/luasrc/view/admin_status/index/mwan.htm
new file mode 100644
index 0000000000..e4b3c06999
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/view/admin_status/index/mwan.htm
@@ -0,0 +1,3 @@
+<%if require("luci.sys").init.enabled("mwan3") then%>
+<%+mwan/overview_status_interface%>
+<%end%>
diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/overview_status_interface.htm b/applications/luci-app-mwan3/luasrc/view/mwan/overview_status_interface.htm
new file mode 100644
index 0000000000..49d120c1ae
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/view/mwan/overview_status_interface.htm
@@ -0,0 +1,75 @@
+<%#
+ Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+ Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+ Licensed to the public under the GNU General Public License v2.
+-%>
+
+<script type="text/javascript">//<![CDATA[
+XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "status", "mwan", "interface_status")%>', null,
+ function(x, status)
+ {
+ var statusDiv = document.getElementById('mwan_status_text');
+ if (status.interfaces)
+ {
+ var statusview = '';
+ for ( var iface in status.interfaces)
+ {
+ var state = '';
+ var css = ''
+ switch (status.interfaces[iface].status)
+ {
+ case 'online':
+ state = '<%:Online%>';
+ css = 'success';
+ break;
+ case 'offline':
+ state = '<%:Offline%>';
+ css = 'danger';
+ break;
+ default:
+ state = '<%:Disabled%>';
+ css = 'warning';
+ break;
+ }
+ statusview += String.format(
+ '<div class="alert-message %s">',
+ css
+ );
+ statusview += String.format(
+ '<div><strong>Interface: </strong>%s</div>',
+ iface
+ );
+ statusview += String.format(
+ '<div><strong>Status: </strong>%s</div>',
+ state
+ );
+ statusview += '</div>'
+ }
+ statusDiv.innerHTML = statusview;
+ }
+ else
+ {
+ statusDiv.innerHTML = '<strong><%:No MWAN interfaces found%></strong>';
+ }
+ }
+ );
+//]]></script>
+
+<style type="text/css">
+ #mwan_status_text > div {
+ display: inline-block;
+ margin: 1rem;
+ padding: 1rem;
+ width: 10rem;
+ float: left;
+ line-height: 125%;
+ }
+</style>
+
+<fieldset id="interface_field" class="cbi-section">
+ <legend><%:MWAN Interfaces%></legend>
+ <div id="mwan_status_text">
+ <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
+ <%:Collecting data...%>
+ </div>
+</fieldset>
diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/status_detail.htm b/applications/luci-app-mwan3/luasrc/view/mwan/status_detail.htm
new file mode 100644
index 0000000000..12700c4a36
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/view/mwan/status_detail.htm
@@ -0,0 +1,39 @@
+<%#
+ Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+ Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+ Licensed to the public under the GNU General Public License v2.
+-%>
+
+<%+header%>
+
+<ul class="cbi-tabmenu">
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/overview")%>"><%:Interface%></a></li>
+ <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/detail")%>"><%:Detail%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/diagnostics")%>"><%:Diagnostics%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/troubleshooting")%>"><%:Troubleshooting%></a></li>
+</ul>
+
+<script type="text/javascript">//<![CDATA[
+ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "status", "mwan", "detailed_status")%>', null,
+ function(x)
+ {
+ var output = document.getElementById('diag-rc-output');
+ output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
+ }
+ );
+//]]></script>
+
+<div class="cbi-map">
+ <h2 name="content"><%:MWAN Status - Detail%></h2>
+ <%if not require("luci.sys").init.enabled("mwan3") then%>
+ <div><strong><%:INFO: MWAN not running%></strong></div>
+ <%end%>
+ <fieldset class="cbi-section">
+ <span id="diag-rc-output">
+ <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align: middle;" />
+ <%:Collecting data...%>
+ </span>
+ </fieldset>
+</div>
+
+<%+footer%>
diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/status_diagnostics.htm b/applications/luci-app-mwan3/luasrc/view/mwan/status_diagnostics.htm
new file mode 100644
index 0000000000..454adcc1cd
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/view/mwan/status_diagnostics.htm
@@ -0,0 +1,90 @@
+<%#
+ Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+ Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+ Licensed to the public under the GNU General Public License v2.
+-%>
+
+<%+header%>
+
+<ul class="cbi-tabmenu">
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/overview")%>"><%:Interface%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/detail")%>"><%:Detail%></a></li>
+ <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/diagnostics")%>"><%:Diagnostics%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/troubleshooting")%>"><%:Troubleshooting%></a></li>
+</ul>
+
+<%
+ local uci = require "luci.model.uci"
+
+ local iface = {}
+
+ uci.cursor():foreach("mwan3", "interface",
+ function (section)
+ table.insert(iface, section[".name"])
+ end
+ )
+%>
+
+<script type="text/javascript">//<![CDATA[
+ var stxhr = new XHR();
+
+ function update_status(iface, task)
+ {
+ var output = document.getElementById('diag-rc-output');
+
+ output.innerHTML =
+ '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align: middle;" />' +
+ "<%:Waiting for command to complete...%>"
+ ;
+
+ output.parentNode.style.display = 'block';
+ output.style.display = 'inline';
+
+ stxhr.post('<%=url('admin/status/mwan')%>/diagnostics_display' + '/' + iface + '/' + task, { token: '<%=token%>' },
+ function(x)
+ {
+ output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
+ }
+ );
+ }
+//]]></script>
+
+<form method="post" action="<%=url('admin/network/diagnostics')%>">
+ <div class="cbi-map">
+ <h2 name="content"><%:MWAN Status - Diagnostics%></h2>
+ <%if not require("luci.sys").init.enabled("mwan3") then%>
+ <div><strong><%:INFO: MWAN not running%></strong></div>
+ <%end%>
+ <fieldset class="cbi-section">
+ <br />
+
+ <div style="width:30%; float:left">
+ <label class="cbi-value-title"><%:Interface%></label>
+ <select name="iface" style="width:auto">
+ <% for _, z in ipairs(iface) do -%><option value="<%=z%>"><%=z%></option><%- end %>
+ </select>
+ </div>
+
+ <div style="width:30%; float:left">
+ <label class="cbi-value-title"><%:Task%></label>
+ <select name="task" style="width:auto">
+ <option value="ping_gateway"><%:Ping default gateway%></option>
+ <option value="ping_trackips"><%:Ping tracking IP%></option>
+ <option value="check_rules"><%:Check IP rules%></option>
+ <option value="check_routes"><%:Check routing table%></option>
+ <option value="hotplug_ifup"><%:Hotplug ifup%></option>
+ <option value="hotplug_ifdown"><%:Hotplug ifdown%></option>
+ </select>
+ </div>
+
+ <div style="width:30%; float:left">
+ <input type="button" value="<%:Execute%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.iface.value, this.form.task.value)"/>
+ </div>
+ </fieldset>
+ </div>
+ <fieldset class="cbi-section" style="display:none">
+ <span id="diag-rc-output"></span>
+ </fieldset>
+</form>
+
+<%+footer%>
diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/status_interface.htm b/applications/luci-app-mwan3/luasrc/view/mwan/status_interface.htm
new file mode 100644
index 0000000000..962cde521d
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/view/mwan/status_interface.htm
@@ -0,0 +1,20 @@
+<%#
+ Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+ Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+ Licensed to the public under the GNU General Public License v2.
+-%>
+
+<%+header%>
+
+<ul class="cbi-tabmenu">
+ <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/overview")%>"><%:Interface%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/detail")%>"><%:Detail%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/diagnostics")%>"><%:Diagnostics%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/troubleshooting")%>"><%:Troubleshooting%></a></li>
+</ul>
+
+
+<div class="cbi-map">
+ <%+mwan/overview_status_interface%>
+</div>
+<%+footer%>
diff --git a/applications/luci-app-mwan3/luasrc/view/mwan/status_troubleshooting.htm b/applications/luci-app-mwan3/luasrc/view/mwan/status_troubleshooting.htm
new file mode 100644
index 0000000000..a20516bd2a
--- /dev/null
+++ b/applications/luci-app-mwan3/luasrc/view/mwan/status_troubleshooting.htm
@@ -0,0 +1,39 @@
+<%#
+ Copyright 2014 Aedan Renner <chipdankly@gmail.com>
+ Copyright 2018 Florian Eckert <fe@dev.tdt.de>
+ Licensed to the public under the GNU General Public License v2.
+-%>
+
+<%+header%>
+
+<ul class="cbi-tabmenu">
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/overview")%>"><%:Interface%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/detail")%>"><%:Detail%></a></li>
+ <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/diagnostics")%>"><%:Diagnostics%></a></li>
+ <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/status/mwan/troubleshooting")%>"><%:Troubleshooting%></a></li>
+</ul>
+
+<script type="text/javascript">//<![CDATA[
+ XHR.poll(15, '<%=luci.dispatcher.build_url("admin", "status", "mwan", "troubleshooting_display")%>', null,
+ function(x)
+ {
+ var output = document.getElementById('diag-rc-output');
+ output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
+ }
+ );
+//]]></script>
+
+<div class="cbi-map">
+ <h2 name="content"><%:MWAN Status - Troubleshooting%></h2>
+ <%if not require("luci.sys").init.enabled("mwan3") then%>
+ <div><strong><%:INFO: MWAN not running%></strong></div>
+ <%end%>
+ <fieldset class="cbi-section">
+ <span id="diag-rc-output">
+ <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align: middle;" />
+ <%:Collecting data...%>
+ </span>
+ </fieldset>
+</div>
+
+<%+footer%>
diff --git a/applications/luci-app-mwan3/po/ja/mwan3.po b/applications/luci-app-mwan3/po/ja/mwan3.po
new file mode 100644
index 0000000000..a5826926dd
--- /dev/null
+++ b/applications/luci-app-mwan3/po/ja/mwan3.po
@@ -0,0 +1,539 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.0.7\n"
+"Last-Translator: INAGAKI Hiroshi <musashino.open@gmail.com>\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"Language: ja\n"
+
+msgid "%d hour"
+msgstr "%d 時間"
+
+msgid "%d minute"
+msgstr "%d 分"
+
+msgid "%d minutes"
+msgstr "%d 分"
+
+msgid "%d second"
+msgstr "%d 秒"
+
+msgid "%d seconds"
+msgstr "%d 秒"
+
+msgid ""
+"Acceptable values: 1-100. This many Tracking IP addresses must respond for "
+"the link to be deemed up"
+msgstr ""
+"利用可能な値: 1-100。上記の追跡 IP の合計個数のうち、Up 状態と判定するために"
+"に必要な、レスポンスが返された追跡 IP アドレスの個数です。"
+
+msgid "Acceptable values: 1-1000. Defaults to 1 if not set"
+msgstr "利用可能な値: 1-1000。空欄の場合のデフォルトは1です。"
+
+msgid "Acceptable values: 1-256. Defaults to 1 if not set"
+msgstr "利用可能な値: 1-256。空欄の場合のデフォルトは1です。"
+
+msgid "Check IP rules"
+msgstr "IP ルールのチェック"
+
+msgid "Check link quality"
+msgstr "リンク品質のチェック"
+
+msgid "Check routing table"
+msgstr "ルーティング テーブルのチェック"
+
+msgid "Collecting data..."
+msgstr "データ収集中です..."
+
+msgid "Destination address"
+msgstr "宛先アドレス"
+
+msgid "Destination port"
+msgstr "宛先ポート"
+
+msgid "Detail"
+msgstr "詳細"
+
+msgid "Diagnostics"
+msgstr "診断機能"
+
+msgid "Disabled"
+msgstr "無効"
+
+msgid ""
+"Downed interface will be deemed up after this many successful ping tests"
+msgstr ""
+"Down 状態のインターフェースが Up 状態と判断されるまでに要する ping テストの成"
+"功回数です。"
+
+msgid "Enabled"
+msgstr "有効"
+
+msgid "Enter value in hex, starting with <code>0x</code>"
+msgstr "<code>0x</code> で始まる16進数の値を入力してください。"
+
+msgid "Execute"
+msgstr "実行"
+
+msgid "Expect interface state on up event"
+msgstr "Up イベント時に予想されるインターフェースの状態です。"
+
+msgid "Failure interval"
+msgstr "障害検出 インターバル"
+
+msgid "Firewall mask"
+msgstr "ファイアウォール マスク"
+
+msgid "Flush conntrack table"
+msgstr "conntrack テーブルのクリア"
+
+msgid "Flush global firewall conntrack table on interface events"
+msgstr ""
+"インターフェース イベント時にグローバル ファイアウォール conntrack テーブルを"
+"クリアします。"
+
+msgid "Globals"
+msgstr "全般"
+
+msgid "Hotplug ifdown"
+msgstr "ホットプラグ ifdown"
+
+msgid "Hotplug ifup"
+msgstr "ホットプラグ ifup"
+
+msgid "INFO: MWAN not running"
+msgstr "情報: MWAN は実行されていません"
+
+msgid "IPset"
+msgstr "IPset"
+
+msgid "IPv4"
+msgstr "IPv4"
+
+msgid "IPv6"
+msgstr "IPv6"
+
+msgid "Initial state"
+msgstr "初期状態"
+
+msgid "Interface"
+msgstr "インターフェース"
+
+msgid "Interface down"
+msgstr "インターフェース Down"
+
+msgid "Interface up"
+msgstr "インターフェース Up"
+
+msgid "Interface will be deemed down after this many failed ping tests"
+msgstr ""
+"インターフェースが Down 状態と判断されるまでに要する ping テストの失敗回数で"
+"す。"
+
+msgid "Interfaces"
+msgstr "インターフェース"
+
+msgid "Internet Protocol"
+msgstr "インターネット プロトコル"
+
+msgid "Keep failure interval"
+msgstr ""
+
+msgid "Keep ping failure interval during failure state"
+msgstr ""
+
+msgid "Last resort"
+msgstr "最終手段"
+
+msgid "Load Balancing"
+msgstr "負荷分散"
+
+msgid "Loading"
+msgstr "読込中"
+
+msgid "Local source interface"
+msgstr ""
+
+msgid "MWAN - Globals"
+msgstr "MWAN - グローバル"
+
+msgid "MWAN - Interfaces"
+msgstr "MWAN - インターフェース"
+
+msgid "MWAN - Members"
+msgstr "MWAN - メンバー"
+
+msgid "MWAN - Notification"
+msgstr "MWAN - 通知"
+
+msgid "MWAN - Policies"
+msgstr "MWAN - ポリシー"
+
+msgid "MWAN - Rules"
+msgstr "MWAN - ルール"
+
+msgid "MWAN Interface Configuration - %s"
+msgstr "MWAN インターフェース設定 - %s"
+
+msgid "MWAN Interfaces"
+msgstr "MWAN インターフェース"
+
+msgid "MWAN Member Configuration - %s"
+msgstr "MWAN メンバー設定 - %s"
+
+msgid "MWAN Policy Configuration - %s"
+msgstr "MWAN ポリシー設定 - %s"
+
+msgid "MWAN Rule Configuration - %s"
+msgstr "MWAN ルール設定 - %s"
+
+msgid "MWAN Status - Detail"
+msgstr "MWAN ステータス - 詳細"
+
+msgid "MWAN Status - Diagnostics"
+msgstr "MWAN ステータス - 診断"
+
+msgid "MWAN Status - Troubleshooting"
+msgstr "MWAN ステータス - トラブルシューティング"
+
+msgid ""
+"MWAN supports up to 252 physical and/or logical interfaces<br />MWAN "
+"requires that all interfaces have a unique metric configured in /etc/config/"
+"network<br />Names must match the interface name found in /etc/config/"
+"network<br />Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br /"
+">Interfaces may not share the same name as configured members, policies or "
+"rules"
+msgstr ""
+"MWAN は、252個までの物理または論理、あるいは両方のインターフェースをサポート"
+"します。<br />MWAN は、全てのインターフェースが /etc/config/network で設定さ"
+"れるユニークなメトリックを持つことを必要とします。<br />下記 \"インターフェー"
+"ス\" の名前は、 /etc/config/network に存在するインターフェース名と同じでなけ"
+"ればなりません。<br />名前は A-Z, a-z, 0-9, _ を含むことができますが、スペー"
+"スは使用できません。<br />インターフェースには、設定済みのメンバーやポリ"
+"シー、ルールと同じ名前を使用することはできません。"
+
+msgid "Max packet latency [ms]"
+msgstr "最大パケットレイテンシ [ms]"
+
+msgid "Max packet loss [%]"
+msgstr "最大パケットロス [%]"
+
+msgid ""
+"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or "
+"as a portrange (eg \"1024:2048\") without quotes"
+msgstr ""
+"単一または複数のポート(例: \"22\" または \"80,443\")、あるいはポートの範囲"
+"(例: \"1024:2048\")を、クオーテーション無しで指定することができます。"
+
+msgid "Member"
+msgstr "メンバー"
+
+msgid "Member used"
+msgstr "使用されるメンバー"
+
+msgid "Members"
+msgstr "メンバー"
+
+msgid ""
+"Members are profiles attaching a metric and weight to an MWAN interface<br /"
+">Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />Members "
+"may not share the same name as configured interfaces, policies or rules"
+msgstr ""
+"メンバーは、MWAN インターフェースのメトリックおよびウエイトを関連付けたプロ"
+"ファイルです。<br />名前は A-Z, a-z, 0-9, _ を含むことができますが、スペース"
+"は使用できません。<br />メンバーには、設定済みのインターフェースやポリシー、"
+"ルールと同じ名前を使用することはできません。"
+
+msgid "Members assigned"
+msgstr "アサイン済みメンバー"
+
+msgid "Metric"
+msgstr "メトリック"
+
+msgid "Min packet latency [ms]"
+msgstr "最小パケットレイテンシ [ms]"
+
+msgid "Min packet loss [%]"
+msgstr "最小パケットロス [%]"
+
+msgid ""
+"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/"
+"youtube.com/youtube\")"
+msgstr ""
+"IPset ルールの名前です。このルールは、 /etc/dnsmasq.conf で必要です。(例: "
+"\"ipset=/youtube.com/youtube\")"
+
+msgid "No"
+msgstr "いいえ"
+
+msgid "No MWAN interfaces found"
+msgstr "MWAN インターフェースが見つかりません"
+
+msgid "Notification"
+msgstr "通知"
+
+msgid "Offline"
+msgstr "オフライン"
+
+msgid "Online"
+msgstr "オンライン"
+
+msgid "Ping count"
+msgstr "Ping 回数"
+
+msgid "Ping default gateway"
+msgstr "Ping デフォルト ゲートウェイ"
+
+msgid "Ping interval"
+msgstr "Ping インターバル"
+
+msgid "Ping interval during failure detection"
+msgstr "障害検出中の Ping 実行間隔です。"
+
+msgid "Ping interval during failure recovering"
+msgstr "障害復旧中の Ping 実行間隔です。"
+
+msgid "Ping size"
+msgstr "Ping サイズ"
+
+msgid "Ping timeout"
+msgstr "Ping タイムアウト"
+
+msgid "Ping tracking IP"
+msgstr "Ping トラッキング IP"
+
+msgid "Policies"
+msgstr "ポリシー"
+
+msgid ""
+"Policies are profiles grouping one or more members controlling how MWAN "
+"distributes traffic<br />Member interfaces with lower metrics are used "
+"first<br />Member interfaces with the same metric will be load-balanced<br /"
+">Load-balanced member interfaces distribute more traffic out those with "
+"higher weights<br />Names may contain characters A-Z, a-z, 0-9, _ and no "
+"spaces<br />Names must be 15 characters or less<br />Policies may not share "
+"the same name as configured interfaces, members or rules"
+msgstr ""
+"ポリシーは、MWANがどのようにトラフィックの分配を行うかを制御する、1つ以上のメ"
+"ンバーをグループ化するプロファイルです。<br />最小のメトリックを持つメンバー "
+"インターフェースが最初に使用されます。同じメトリックを持つ複数のインター"
+"フェースでは、負荷分散を行います。<br />負荷分散に設定されたメンバー インター"
+"フェースでは、ウェイトの値が大きい方により多くのトラフィックを分配します。"
+"<br />名前は A-Z, a-z, 0-9, _ を含むことができますが、スペースは使用できませ"
+"ん。また、15文字以内でなければなりません。<br />ポリシーでは、設定済みのイン"
+"ターフェースやメンバー、ルールと同じ名前を使用することはできません。"
+
+msgid "Policy"
+msgstr "ポリシー"
+
+msgid "Policy assigned"
+msgstr "アサイン済みポリシー"
+
+msgid "Protocol"
+msgstr "プロトコル"
+
+msgid "Recovery interval"
+msgstr "障害復旧 インターバル"
+
+msgid "Rule"
+msgstr "ルール"
+
+msgid "Rules"
+msgstr "ルール"
+
+msgid ""
+"Rules specify which traffic will use a particular MWAN policy<br />Rules are "
+"based on IP address, port or protocol<br />Rules are matched from top to "
+"bottom<br />Rules below a matching rule are ignored<br />Traffic not "
+"matching any rule is routed using the main routing table<br />Traffic "
+"destined for known (other than default) networks is handled by the main "
+"routing table<br />Traffic matching a rule, but all WAN interfaces for that "
+"policy are down will be blackholed<br />Names may contain characters A-Z, a-"
+"z, 0-9, _ and no spaces<br />Rules may not share the same name as configured "
+"interfaces, members or policies"
+msgstr ""
+"ルールは、どのトラフィックが特定の MWAN ポリシーを使用するかを指定します<br /"
+">ルールは IP アドレスやポート、プロトコルに基づいています<br />ルールは上から"
+"下へマッチングが行われます<br />合致したルールより下のルールは無視されます"
+"<br />いずれのルールにもマッチしないトラフィックは、メインのルーティングテー"
+"ブルを使用してルーティングされます<br />既知(デフォルト以外)のネットワーク"
+"へのトラフィックは、メインのルーティングテーブルによって制御されます<br />ト"
+"ラフィックがルールに合致しても、全 WAN インターフェースが down の場合は "
+"blackhole 状態となります<br />名前は A-Z, a-z, 0-9, _ を含むことができます"
+"が、スペースは使用できません<br />ルールは、設定済みのインターフェースやメン"
+"バー、ポリシーと同じ名前を使用することはできません。"
+
+msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"
+msgstr "秒。利用可能な値: 1-1000000。空欄の場合のデフォルト値は600です。"
+
+msgid "Source address"
+msgstr "送信元アドレス"
+
+msgid "Source port"
+msgstr "送信元ポート"
+
+msgid "Sticky"
+msgstr "Sticky"
+
+msgid "Sticky timeout"
+msgstr "Sticky タイムアウト"
+
+msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"
+msgstr "CIDR 表記のサポート(例: \"192.168.100.0/24\")"
+
+msgid "Task"
+msgstr "タスク"
+
+msgid "There are currently %d of %d supported interfaces configured"
+msgstr "現在、%d 個中 %d 個のサポートされたインターフェースが設定済みです。"
+
+msgid ""
+"This displays the metric assigned to this interface in /etc/config/network"
+msgstr ""
+"/etc/config/network で、このインターフェースに割り当てられたメトリックです。"
+
+msgid ""
+"This hostname or IP address will be pinged to determine if the link is up or "
+"down. Leave blank to assume interface is always online"
+msgstr ""
+"リンクの Up または Down 状態を判定するために、このホスト名または IP アドレス"
+"に対して Ping の送信が行われます。常にオンラインとする場合、空欄のままにしま"
+"す。"
+
+msgid ""
+"This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+">The file is also preserved during sysupgrade.<br /><br />Notes:<br />This "
+"file is interpreted as a shell script.<br />The first line of the script "
+"must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning with # are "
+"comments and are not executed.<br />Put your custom mwan3 action here, they "
+"will<br />be executed with each netifd hotplug interface event<br />on "
+"interfaces for which mwan3 is enabled.<br /><br />There are three main "
+"environment variables that are passed to this script.<br /><br />$ACTION "
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
+"このセクションでは、 \"/etc/mwan3.user\" の内容を変更することができます。"
+"<br />このファイルも sysupgrade の際に保持されます。<br /><br />注意: <br />"
+"このファイルはシェルスクリプトとして解釈されます。<br />最初の行は &#34;#!/"
+"bin/sh&#34; である必要があります(クォーテーション不要)。<br /># で始まる行"
+"はコメントであり、実行されません。<br />mwan3 のカスタム動作をここに入力して"
+"ください。<br />これらは、mwan3 で有効なインターフェースの<br /> netifd "
+"hotplug インターフェース イベント毎に実行されます。<br /><br />このスクリプト"
+"に受け渡される主に3つの環境変数が利用できます。<br /><br />$ACTION<br />* "
+"\"ifup\" は netifd と mwan3track により呼び出されます<br />* \"ifdown\" は "
+"netifd と mwan3track により呼び出されます<br />* \"connected\" はトラッキング"
+"が成功した際に mwan3track にのみにより呼び出されます<br />* \"disconnected\" "
+"は トラッキングが失敗した際に mwan3track のみにより呼び出されます<br />"
+"$INTERFACE up または down したインターフェース名(例: \"wan\" や \"wwan\")"
+"<br />$DEVICE up または down したインターフェースの物理デバイス名(例: "
+"\"eth0\" や \"wwan0\")<br /><br />"
+
+msgid "Tracking hostname or IP address"
+msgstr "追跡ホスト名または IP アドレス"
+
+msgid "Tracking method"
+msgstr "追跡方式"
+
+msgid "Tracking reliability"
+msgstr "追跡の信頼性"
+
+msgid ""
+"Traffic from the same source IP address that previously matched this rule "
+"within the sticky timeout period will use the same WAN interface"
+msgstr ""
+"以前このルールにマッチした同じアクセス元 IP アドレスからのトラフィックが、再"
+"度 Sticky 制限時間内にマッチした場合には、同じ WAN インターフェースが使用され"
+"ます。"
+
+msgid "Troubleshooting"
+msgstr "トラブルシューティング"
+
+msgid ""
+"Use the IP address of this interface as source IP address for traffic "
+"initiated by the router itself"
+msgstr ""
+"ルーター自身によって発生するトラフィックのアクセス元 IP アドレスとして、この"
+"インターフェースの IP アドレスが使用されます。"
+
+msgid "View the content of /etc/protocols for protocol description"
+msgstr "プロトコルの説明については、 /etc/protocols の内容を確認してください"
+
+msgid "WARNING: %d interfaces are configured exceeding the maximum of %d!"
+msgstr ""
+"警告: %d 個のインターフェースが、最大個数の %d 個 を超えて設定されています!"
+
+msgid "WARNING: Interface %s are not found in /etc/config/network"
+msgstr "警告: インターフェース %s が /etc/config/network に見つかりません"
+
+msgid "WARNING: Interface %s has a duplicate metric %s configured"
+msgstr "警告: インターフェース %s に重複するメトリック %s が設定されています"
+
+msgid ""
+"WARNING: Interface %s has a higher reliability requirement than tracking "
+"hosts (%d)"
+msgstr ""
+"警告: インターフェース %s は追跡ホスト数 (%d) よりも高い追跡信頼性の値が設定"
+"されています"
+
+msgid "WARNING: Interface %s has no default route in the main routing table"
+msgstr ""
+"警告: インターフェース %s はメインのルーティング テーブル内でデフォルトルート"
+"がありません"
+
+msgid "WARNING: Policy %s has exceeding the maximum name of 15 characters"
+msgstr "警告: ポリシー %s の名前は15文字の最大文字数を超えています"
+
+msgid ""
+"WARNING: Rule %s have a port configured with no or improper protocol "
+"specified!"
+msgstr ""
+"警告: ルール %s はプロトコル指定が不適切、または無いポートが設定されていま"
+"す!"
+
+msgid "Waiting for command to complete..."
+msgstr "コマンドを実行中です..."
+
+msgid "Weight"
+msgstr "ウエイト"
+
+msgid ""
+"When all policy members are offline use this behavior for matched traffic"
+msgstr ""
+"ポリシーの全メンバーがオフラインの場合、合致したトラフィックに対してこのふる"
+"まいが使用されます。"
+
+msgid "Yes"
+msgstr "はい"
+
+msgid "always"
+msgstr "always"
+
+msgid "blackhole (drop)"
+msgstr "blackhole (drop)"
+
+msgid "default (use main routing table)"
+msgstr "デフォルト(メインのルーティング テーブルを使用)"
+
+msgid "ifdown"
+msgstr "ifdown"
+
+msgid "ifup"
+msgstr "ifup"
+
+msgid "never"
+msgstr "never"
+
+msgid "unreachable (reject)"
+msgstr "unreachable (reject)"
diff --git a/applications/luci-app-mwan3/po/ru/mwan3.po b/applications/luci-app-mwan3/po/ru/mwan3.po
new file mode 100644
index 0000000000..140c537e73
--- /dev/null
+++ b/applications/luci-app-mwan3/po/ru/mwan3.po
@@ -0,0 +1,568 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: LuCI: mwan3\n"
+"POT-Creation-Date: 2017-09-14 16:00+0300\n"
+"PO-Revision-Date: 2018-01-19 20:57+0300\n"
+"Language-Team: http://cyber-place.ru\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.7.1\n"
+"Last-Translator: Vladimir aka sunny <picfun@ya.ru>\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"Language: ru\n"
+"Project-Info: Это технический перевод, не дословный. Главное-удобный русский "
+"интерфейс, все проверялось в графическом режиме, совместим с другими apps\n"
+
+msgid "%d hour"
+msgstr "%d час"
+
+msgid "%d minute"
+msgstr "%d минута"
+
+msgid "%d minutes"
+msgstr "%d минут"
+
+msgid "%d second"
+msgstr "%d секунда"
+
+msgid "%d seconds"
+msgstr "%d секунд"
+
+msgid ""
+"Acceptable values: 1-100. This many Tracking IP addresses must respond for "
+"the link to be deemed up"
+msgstr ""
+"Допустимые значения: 1-100. Установите количество ответов IP-адресов. <br /"
+">Сколько раз они должны ответить, чтобы соединение было признано активным."
+
+msgid "Acceptable values: 1-1000. Defaults to 1 if not set"
+msgstr "Допустимые значения: 1-1000. По умолчанию 1, если значение не задано."
+
+msgid "Acceptable values: 1-256. Defaults to 1 if not set"
+msgstr "Допустимые значения: 1-256 По умолчанию 1, если значение не задано."
+
+msgid "Check IP rules"
+msgstr "Проверить правила IP"
+
+msgid "Check link quality"
+msgstr ""
+
+msgid "Check routing table"
+msgstr "Проверить таблицу маршрутизации"
+
+msgid "Collecting data..."
+msgstr "Сбор данных..."
+
+msgid "Destination address"
+msgstr "Адрес назначения"
+
+msgid "Destination port"
+msgstr "Порт назначения"
+
+msgid "Detail"
+msgstr "Подробно"
+
+msgid "Diagnostics"
+msgstr "Диагностика"
+
+msgid "Disabled"
+msgstr "Отключено"
+
+msgid ""
+"Downed interface will be deemed up after this many successful ping tests"
+msgstr ""
+"Интерфейс будет считаться отключенным, после продолжительных пинг-запросов."
+
+msgid "Enabled"
+msgstr "Включено"
+
+msgid "Enter value in hex, starting with <code>0x</code>"
+msgstr "Введите значение в шестнадцатеричной форме, начиная с <code>0x</code>."
+
+msgid "Execute"
+msgstr "Выполнить"
+
+msgid "Expect interface state on up event"
+msgstr "Ожидание "
+
+msgid "Failure interval"
+msgstr "Интервал отказа"
+
+msgid "Firewall mask"
+msgstr "Маска межсетевого экрана"
+
+msgid "Flush conntrack table"
+msgstr "Сбросьте conntrack таблицу"
+
+msgid "Flush global firewall conntrack table on interface events"
+msgstr ""
+"Сбросьте глобальные настройки межсетевого экрана conntrack таблицы по "
+"истории интерфейса."
+
+msgid "Globals"
+msgstr "Общие"
+
+msgid "Hotplug ifdown"
+msgstr "Hotplug ifdown"
+
+msgid "Hotplug ifup"
+msgstr "Hotplug ifup"
+
+msgid "INFO: MWAN not running"
+msgstr ""
+
+msgid "IPset"
+msgstr "IPset"
+
+msgid "IPv4"
+msgstr "IPv4"
+
+msgid "IPv6"
+msgstr "IPv6"
+
+msgid "Initial state"
+msgstr "Исходное состояние"
+
+msgid "Interface"
+msgstr "Интерфейс"
+
+msgid "Interface down"
+msgstr "Интерфейс отключить"
+
+msgid "Interface up"
+msgstr "Интерфейс включить"
+
+msgid "Interface will be deemed down after this many failed ping tests"
+msgstr ""
+"Интерфейс будут считать отключенным, после данного количества пинг-запросов."
+
+msgid "Interfaces"
+msgstr "Интерфейсы"
+
+msgid "Internet Protocol"
+msgstr "Протокол интернета"
+
+msgid "Keep failure interval"
+msgstr "Сохранить интервал сбоя"
+
+msgid "Keep ping failure interval during failure state"
+msgstr "Сохранить интервал сбоя пинг-запроса, во время состояния сбоя."
+
+msgid "Last resort"
+msgstr "Последнее средство"
+
+msgid "Load Balancing"
+msgstr "Балансировка WAN трафика"
+
+msgid "Loading"
+msgstr "Загрузка"
+
+msgid "Local source interface"
+msgstr "Локальный исходящий интефейс"
+
+msgid "MWAN - Globals"
+msgstr "MWAN - Общие"
+
+msgid "MWAN - Interfaces"
+msgstr "MWAN - Интерфейсы"
+
+msgid "MWAN - Members"
+msgstr "MWAN - Узлы"
+
+msgid "MWAN - Notification"
+msgstr "MWAN - Уведомления"
+
+msgid "MWAN - Policies"
+msgstr "MWAN - Политики"
+
+msgid "MWAN - Rules"
+msgstr "MWAN - Правила"
+
+msgid "MWAN Interface Configuration - %s"
+msgstr "Настройка интерфейсов MWAN - %s"
+
+msgid "MWAN Interfaces"
+msgstr ""
+
+msgid "MWAN Member Configuration - %s"
+msgstr "MWAN настройка узлов - %s"
+
+msgid "MWAN Policy Configuration - %s"
+msgstr "MWAN настройка политики - %s"
+
+msgid "MWAN Rule Configuration - %s"
+msgstr "MWAN настройка правил - %s"
+
+msgid "MWAN Status - Detail"
+msgstr "Состояние MWAN - Подробно"
+
+msgid "MWAN Status - Diagnostics"
+msgstr "Состояние MWAN - Диагностика"
+
+msgid "MWAN Status - Troubleshooting"
+msgstr "Состояние MWAN - Устранение неполадок"
+
+msgid ""
+"MWAN supports up to 252 physical and/or logical interfaces<br />MWAN "
+"requires that all interfaces have a unique metric configured in /etc/config/"
+"network<br />Names must match the interface name found in /etc/config/"
+"network<br />Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br /"
+">Interfaces may not share the same name as configured members, policies or "
+"rules"
+msgstr ""
+"MWAN поддерживает до 252 физических и / или логических интерфейсов.<br /"
+">MWAN требует, чтобы все интерфейсы имели уникальную метрику, настроенную в "
+"config файле /etc/config/network.<br />Имена должны соответствовать имени "
+"интерфейса, найденному в /etc/config/network.<br />Имена могут содержать "
+"символы A-Z, a-z, 0-9, _ и пробелы.<br />Интерфейсы не могут иметь "
+"одинаковые имена с настроенными узлами, политиками или правилами."
+
+msgid "Max packet latency [ms]"
+msgstr ""
+
+msgid "Max packet loss [%]"
+msgstr ""
+
+msgid ""
+"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or "
+"as a portrange (eg \"1024:2048\") without quotes"
+msgstr ""
+"Может быть введено как один или несколько портов (например, '22' или "
+"'80,443') или как диапазон портов (например, '1024:2048') без кавычек."
+
+msgid "Member"
+msgstr "Узел"
+
+msgid "Member used"
+msgstr "Используемый узел"
+
+msgid "Members"
+msgstr "Узлы"
+
+msgid ""
+"Members are profiles attaching a metric and weight to an MWAN interface<br /"
+">Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />Members "
+"may not share the same name as configured interfaces, policies or rules"
+msgstr ""
+"Узлы имеют профили, содержащие метрику и вес к интерфейсу MWAN.<br />Имена "
+"могут содержать символы A-Z, a-z, 0-9, _ и пробелы.<br />Узлы не могут иметь "
+"одинаковые имена с настроенными интерфейсами, политиками или правилами."
+
+msgid "Members assigned"
+msgstr "Назначенные узлы"
+
+msgid "Metric"
+msgstr "Метрика"
+
+msgid "Min packet latency [ms]"
+msgstr ""
+
+msgid "Min packet loss [%]"
+msgstr ""
+
+msgid ""
+"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/"
+"youtube.com/youtube\")"
+msgstr ""
+"Имя IPset правила. Требуется правило IPset в /etc/dnsmasq.conf (например "
+"\"ipset=/youtube.com/youtube\")."
+
+msgid "No"
+msgstr "Нет"
+
+msgid "No MWAN interfaces found"
+msgstr "Интерфейсы MWAN не найдены"
+
+msgid "Notification"
+msgstr "Уведомления"
+
+msgid "Offline"
+msgstr "Отключен"
+
+msgid "Online"
+msgstr "Онлайн"
+
+msgid "Ping count"
+msgstr "Кол-во пинг-запросов"
+
+msgid "Ping default gateway"
+msgstr "Пинг-запрос шлюза по умолчанию"
+
+msgid "Ping interval"
+msgstr "Интервал пинг-запроса"
+
+msgid "Ping interval during failure detection"
+msgstr "Интервал пинг-запроса во время обнаружения отказов."
+
+msgid "Ping interval during failure recovering"
+msgstr "Интервал пинг-запроса при сбое восстановления."
+
+msgid "Ping size"
+msgstr "Размер пинг-запроса"
+
+msgid "Ping timeout"
+msgstr "Время ожидания пинг-запроса"
+
+msgid "Ping tracking IP"
+msgstr "Пинг-запрос отслеживания IP"
+
+msgid "Policies"
+msgstr "Политики"
+
+msgid ""
+"Policies are profiles grouping one or more members controlling how MWAN "
+"distributes traffic<br />Member interfaces with lower metrics are used "
+"first<br />Member interfaces with the same metric will be load-balanced<br /"
+">Load-balanced member interfaces distribute more traffic out those with "
+"higher weights<br />Names may contain characters A-Z, a-z, 0-9, _ and no "
+"spaces<br />Names must be 15 characters or less<br />Policies may not share "
+"the same name as configured interfaces, members or rules"
+msgstr ""
+"Политики это профили, объединяющие один или несколько узлов, контролирующих, "
+"как MWAN распределяет трафик.<br />Сначала используются интерфейсы-узлы с "
+"более низкими метриками. Интерфейсы с одинаковым метрическим балансом "
+"нагрузки.<br />Интерфейсы элементов с балансировкой нагрузки распределяют "
+"больше трафика с более высокими значениями.<br />Имена могут содержать "
+"символы A-Z, a-z, 0-9, _ и пробелы. Имена должны быть не более 15 символов."
+"<br />Политики не могут иметь одинаковые имена с настроенными интерфейсами, "
+"узлами или правилами."
+
+msgid "Policy"
+msgstr "Политика"
+
+msgid "Policy assigned"
+msgstr "Назначенная политика"
+
+msgid "Protocol"
+msgstr "Протокол"
+
+msgid "Recovery interval"
+msgstr "Интервал восстановления"
+
+msgid "Rule"
+msgstr "Правило"
+
+msgid "Rules"
+msgstr "Правила"
+
+msgid ""
+"Rules specify which traffic will use a particular MWAN policy<br />Rules are "
+"based on IP address, port or protocol<br />Rules are matched from top to "
+"bottom<br />Rules below a matching rule are ignored<br />Traffic not "
+"matching any rule is routed using the main routing table<br />Traffic "
+"destined for known (other than default) networks is handled by the main "
+"routing table<br />Traffic matching a rule, but all WAN interfaces for that "
+"policy are down will be blackholed<br />Names may contain characters A-Z, a-"
+"z, 0-9, _ and no spaces<br />Rules may not share the same name as configured "
+"interfaces, members or policies"
+msgstr ""
+"Правила определяют, какой трафик будет использовать конкретную политику MWAN."
+"<br />Правила основываются на IP-адресе, порту или протоколе.<br />Список "
+"правил исполняется сверху вниз.<br />Правила, расположенные ниже правила "
+"сопоставления, игнорируются.<br />Трафик, не соответствующий никакому "
+"правилу, маршрутизируется с помощью основной таблицы маршрутизации.<br /"
+">Трафик, предназначенный для известных (не по умолчанию) сетей, "
+"обрабатывается основной таблицей маршрутизации.<br />Трафик соответствует "
+"правилам, но все интерфейсы WAN для этой политики будут заблокированы.<br /"
+">Имена могут содержать символы A-Z, a-z, 0-9, _ , пробелы запрещены.<br /"
+">Правила не могут иметь одинаковые имена с настроенными интерфейсами, узлами "
+"или политиками."
+
+msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"
+msgstr ""
+"Секунд. Допустимые значения: 1-1000000. По умолчанию 600, если значение не "
+"установлено."
+
+msgid "Source address"
+msgstr "Адрес источника"
+
+msgid "Source port"
+msgstr "Порт источника"
+
+msgid "Sticky"
+msgstr "Липкий"
+
+msgid "Sticky timeout"
+msgstr "Липкое значение времени ожидания"
+
+msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"
+msgstr "Поддерживает CIDR нотацию (например '192.168.100.0/24') без кавычек."
+
+msgid "Task"
+msgstr "Задача"
+
+msgid "There are currently %d of %d supported interfaces configured"
+msgstr "В настоящее время настроено %d из %d поддерживаемых интерфейсов."
+
+msgid ""
+"This displays the metric assigned to this interface in /etc/config/network"
+msgstr ""
+"Страница отображает настройки этого интерфейса в config файле network (/etc/"
+"config/network)."
+
+msgid ""
+"This hostname or IP address will be pinged to determine if the link is up or "
+"down. Leave blank to assume interface is always online"
+msgstr ""
+"Это имя хоста или IP-адрес для пинг-запроса, чтобы определить активно ли "
+"соединение или нет.<br />Оставьте пустым, чтобы предположить, что интерфейс "
+"всегда находится в сети."
+
+msgid ""
+"This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+">The file is also preserved during sysupgrade.<br /><br />Notes:<br />This "
+"file is interpreted as a shell script.<br />The first line of the script "
+"must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning with # are "
+"comments and are not executed.<br />Put your custom mwan3 action here, they "
+"will<br />be executed with each netifd hotplug interface event<br />on "
+"interfaces for which mwan3 is enabled.<br /><br />There are three main "
+"environment variables that are passed to this script.<br /><br />$ACTION "
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
+
+msgid "Tracking hostname or IP address"
+msgstr "Отслеживание имени хоста или IP-адреса"
+
+msgid "Tracking method"
+msgstr "Метод отслеживания"
+
+msgid "Tracking reliability"
+msgstr "Надежность отслеживания"
+
+msgid ""
+"Traffic from the same source IP address that previously matched this rule "
+"within the sticky timeout period will use the same WAN interface"
+msgstr ""
+"Трафик с того же IP-адреса источника, который ранее соответствовал этому "
+"правилу в период 'липкого' времени ожидания, будет использовать тот же "
+"интерфейс WAN."
+
+msgid "Troubleshooting"
+msgstr "Устранение неполадок"
+
+msgid ""
+"Use the IP address of this interface as source IP address for traffic "
+"initiated by the router itself"
+msgstr ""
+"Используйте IP-адрес этого интерфейса в качестве IP-адреса источника для "
+"трафика, инициированного самим маршрутизатором."
+
+msgid "View the content of /etc/protocols for protocol description"
+msgstr "Просмотр содержимого файла /etc/protocols для описания протокола."
+
+msgid "WARNING: %d interfaces are configured exceeding the maximum of %d!"
+msgstr ""
+"ВНИМАНИЕ: Интерфейсы %d настроены, превышая установленное ограничение в "
+"количестве %dшт.!"
+
+msgid "WARNING: Interface %s are not found in /etc/config/network"
+msgstr "ВНИМАНИЕ: Интерфейс %s не настроен в config файле /etc/config/network."
+
+msgid "WARNING: Interface %s has a duplicate metric %s configured"
+msgstr ""
+"ВНИМАНИЕ: Интерфейс %s имеет дублирующие метрики настройки %s config файла."
+
+msgid ""
+"WARNING: Interface %s has a higher reliability requirement than tracking "
+"hosts (%d)"
+msgstr ""
+"ВНИМАНИЕ: Интерфейс %s имеет более высокое требование надежности, чем узлы "
+"отслеживания (%d)."
+
+msgid "WARNING: Interface %s has no default route in the main routing table"
+msgstr ""
+"ВНИМАНИЕ: Интерфейс %s не имеет маршрута по умолчанию в основной таблице "
+"маршрутизации."
+
+msgid "WARNING: Policy %s has exceeding the maximum name of 15 characters"
+msgstr ""
+"ВНИМАНИЕ: Имя политики %s превышает установленное ограничение в 15 символов."
+
+msgid ""
+"WARNING: Rule %s have a port configured with no or improper protocol "
+"specified!"
+msgstr "ВНИМАНИЕ: Для правила %s порта не задан протокол или указан неверный!"
+
+msgid "Waiting for command to complete..."
+msgstr "Ожидание завершения выполнения команды..."
+
+msgid "Weight"
+msgstr "Вес"
+
+msgid ""
+"When all policy members are offline use this behavior for matched traffic"
+msgstr ""
+"Когда все члены политики находятся в автономном режиме, используйте это "
+"поведение для сопоставленного трафика."
+
+msgid "Yes"
+msgstr "Да"
+
+msgid "always"
+msgstr "всегда"
+
+msgid "blackhole (drop)"
+msgstr "blackhole (drop)"
+
+msgid "default (use main routing table)"
+msgstr "по умолчанию (использовать основную таблицу маршрутизации)"
+
+msgid "ifdown"
+msgstr "ifdown"
+
+msgid "ifup"
+msgstr "ifup"
+
+msgid "never"
+msgstr "никогда"
+
+msgid "unreachable (reject)"
+msgstr "недоступен (отклонить)"
+
+#~ msgid "Online (tracking active)"
+#~ msgstr "Онлайн (отслеживание активно)"
+
+#~ msgid "MWAN Interface Live Status"
+#~ msgstr "Состояние интерфейса MWAN в настоящее время"
+
+#~ msgid "MWAN status - Interface Live Status"
+#~ msgstr "Состояние MWAN - Интерфейс в настоящее время"
+
+#~ msgid "Online (tracking off)"
+#~ msgstr "Онлайн (отслеживание отключено)"
+
+#~ msgid ""
+#~ "This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+#~ ">The file is also preserved during sysupgrade.<br /><br />Notes:<br /"
+#~ ">This file is interpreted as a shell script.<br />The first line of the "
+#~ "script must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning "
+#~ "with # are comments and are not executed.<br />Put your custom mwan3 "
+#~ "action here, they will<br />be executed with each netifd hotplug "
+#~ "interface event<br />on interfaces for which mwan3 is enabled.<br /><br /"
+#~ ">There are three main environment variables that are passed to this "
+#~ "script.<br /><br />$ACTION Either \"ifup\" or \"ifdown\"<br />$INTERFACE "
+#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan"
+#~ "\")<br />$DEVICE Physical device name which interface went up or down (e."
+#~ "g. \"eth0\" or \"wwan0\")<br /><br />"
+#~ msgstr ""
+#~ "Страница позволяет изменять содержимое файла mwan3.user (/etc/mwan3.user)."
+#~ "<br />Файл также сохраняется во время перепрошивки sysupgrade-совместимым "
+#~ "образом.<br /><br />Примечание:<br />Этот файл интерпретируется как shell "
+#~ "скрипт.<br />Первая строка скрипта должна быть &#34;#!/bin/sh&#34; без "
+#~ "кавычек.<br />Строки начинающиеся с #, являются комментариями и не "
+#~ "исполняются.<br />Поместите свои пользовательские действия mwan3 здесь, "
+#~ "они будут<br />выполняться с каждым событием netifd hotplug "
+#~ "интерфейса<br />на интерфейсах, для которых включен mwan3.<br /><br />В "
+#~ "этот сценарий передаются три основные переменные среды.<br /><br />"
+#~ "$ACTION либо \"ifup\" или \"ifdown\"<br />$INTERFACE - имя интерфейса, "
+#~ "который включили или отключили (например, 'wan' или 'wwan') <br />$DEVICE "
+#~ "- имя физического устройства, чей интерфейс включили или отключили "
+#~ "(например, 'eth0' или 'wwan0')<br /><br />."
diff --git a/applications/luci-app-mwan3/po/templates/mwan3.pot b/applications/luci-app-mwan3/po/templates/mwan3.pot
new file mode 100644
index 0000000000..bcc5e977a5
--- /dev/null
+++ b/applications/luci-app-mwan3/po/templates/mwan3.pot
@@ -0,0 +1,454 @@
+msgid ""
+msgstr "Content-Type: text/plain; charset=UTF-8"
+
+msgid "%d hour"
+msgstr ""
+
+msgid "%d minute"
+msgstr ""
+
+msgid "%d minutes"
+msgstr ""
+
+msgid "%d second"
+msgstr ""
+
+msgid "%d seconds"
+msgstr ""
+
+msgid ""
+"Acceptable values: 1-100. This many Tracking IP addresses must respond for "
+"the link to be deemed up"
+msgstr ""
+
+msgid "Acceptable values: 1-1000. Defaults to 1 if not set"
+msgstr ""
+
+msgid "Acceptable values: 1-256. Defaults to 1 if not set"
+msgstr ""
+
+msgid "Check IP rules"
+msgstr ""
+
+msgid "Check link quality"
+msgstr ""
+
+msgid "Check routing table"
+msgstr ""
+
+msgid "Collecting data..."
+msgstr ""
+
+msgid "Destination address"
+msgstr ""
+
+msgid "Destination port"
+msgstr ""
+
+msgid "Detail"
+msgstr ""
+
+msgid "Diagnostics"
+msgstr ""
+
+msgid "Disabled"
+msgstr ""
+
+msgid ""
+"Downed interface will be deemed up after this many successful ping tests"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "Enter value in hex, starting with <code>0x</code>"
+msgstr ""
+
+msgid "Execute"
+msgstr ""
+
+msgid "Expect interface state on up event"
+msgstr ""
+
+msgid "Failure interval"
+msgstr ""
+
+msgid "Firewall mask"
+msgstr ""
+
+msgid "Flush conntrack table"
+msgstr ""
+
+msgid "Flush global firewall conntrack table on interface events"
+msgstr ""
+
+msgid "Globals"
+msgstr ""
+
+msgid "Hotplug ifdown"
+msgstr ""
+
+msgid "Hotplug ifup"
+msgstr ""
+
+msgid "INFO: MWAN not running"
+msgstr ""
+
+msgid "IPset"
+msgstr ""
+
+msgid "IPv4"
+msgstr ""
+
+msgid "IPv6"
+msgstr ""
+
+msgid "Initial state"
+msgstr ""
+
+msgid "Interface"
+msgstr ""
+
+msgid "Interface down"
+msgstr ""
+
+msgid "Interface up"
+msgstr ""
+
+msgid "Interface will be deemed down after this many failed ping tests"
+msgstr ""
+
+msgid "Interfaces"
+msgstr ""
+
+msgid "Internet Protocol"
+msgstr ""
+
+msgid "Keep failure interval"
+msgstr ""
+
+msgid "Keep ping failure interval during failure state"
+msgstr ""
+
+msgid "Last resort"
+msgstr ""
+
+msgid "Load Balancing"
+msgstr ""
+
+msgid "Loading"
+msgstr ""
+
+msgid "Local source interface"
+msgstr ""
+
+msgid "MWAN - Globals"
+msgstr ""
+
+msgid "MWAN - Interfaces"
+msgstr ""
+
+msgid "MWAN - Members"
+msgstr ""
+
+msgid "MWAN - Notification"
+msgstr ""
+
+msgid "MWAN - Policies"
+msgstr ""
+
+msgid "MWAN - Rules"
+msgstr ""
+
+msgid "MWAN Interface Configuration - %s"
+msgstr ""
+
+msgid "MWAN Interfaces"
+msgstr ""
+
+msgid "MWAN Member Configuration - %s"
+msgstr ""
+
+msgid "MWAN Policy Configuration - %s"
+msgstr ""
+
+msgid "MWAN Rule Configuration - %s"
+msgstr ""
+
+msgid "MWAN Status - Detail"
+msgstr ""
+
+msgid "MWAN Status - Diagnostics"
+msgstr ""
+
+msgid "MWAN Status - Troubleshooting"
+msgstr ""
+
+msgid ""
+"MWAN supports up to 252 physical and/or logical interfaces<br />MWAN "
+"requires that all interfaces have a unique metric configured in /etc/config/"
+"network<br />Names must match the interface name found in /etc/config/"
+"network<br />Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br /"
+">Interfaces may not share the same name as configured members, policies or "
+"rules"
+msgstr ""
+
+msgid "Max packet latency [ms]"
+msgstr ""
+
+msgid "Max packet loss [%]"
+msgstr ""
+
+msgid ""
+"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or "
+"as a portrange (eg \"1024:2048\") without quotes"
+msgstr ""
+
+msgid "Member"
+msgstr ""
+
+msgid "Member used"
+msgstr ""
+
+msgid "Members"
+msgstr ""
+
+msgid ""
+"Members are profiles attaching a metric and weight to an MWAN interface<br /"
+">Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />Members "
+"may not share the same name as configured interfaces, policies or rules"
+msgstr ""
+
+msgid "Members assigned"
+msgstr ""
+
+msgid "Metric"
+msgstr ""
+
+msgid "Min packet latency [ms]"
+msgstr ""
+
+msgid "Min packet loss [%]"
+msgstr ""
+
+msgid ""
+"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/"
+"youtube.com/youtube\")"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "No MWAN interfaces found"
+msgstr ""
+
+msgid "Notification"
+msgstr ""
+
+msgid "Offline"
+msgstr ""
+
+msgid "Online"
+msgstr ""
+
+msgid "Ping count"
+msgstr ""
+
+msgid "Ping default gateway"
+msgstr ""
+
+msgid "Ping interval"
+msgstr ""
+
+msgid "Ping interval during failure detection"
+msgstr ""
+
+msgid "Ping interval during failure recovering"
+msgstr ""
+
+msgid "Ping size"
+msgstr ""
+
+msgid "Ping timeout"
+msgstr ""
+
+msgid "Ping tracking IP"
+msgstr ""
+
+msgid "Policies"
+msgstr ""
+
+msgid ""
+"Policies are profiles grouping one or more members controlling how MWAN "
+"distributes traffic<br />Member interfaces with lower metrics are used "
+"first<br />Member interfaces with the same metric will be load-balanced<br /"
+">Load-balanced member interfaces distribute more traffic out those with "
+"higher weights<br />Names may contain characters A-Z, a-z, 0-9, _ and no "
+"spaces<br />Names must be 15 characters or less<br />Policies may not share "
+"the same name as configured interfaces, members or rules"
+msgstr ""
+
+msgid "Policy"
+msgstr ""
+
+msgid "Policy assigned"
+msgstr ""
+
+msgid "Protocol"
+msgstr ""
+
+msgid "Recovery interval"
+msgstr ""
+
+msgid "Rule"
+msgstr ""
+
+msgid "Rules"
+msgstr ""
+
+msgid ""
+"Rules specify which traffic will use a particular MWAN policy<br />Rules are "
+"based on IP address, port or protocol<br />Rules are matched from top to "
+"bottom<br />Rules below a matching rule are ignored<br />Traffic not "
+"matching any rule is routed using the main routing table<br />Traffic "
+"destined for known (other than default) networks is handled by the main "
+"routing table<br />Traffic matching a rule, but all WAN interfaces for that "
+"policy are down will be blackholed<br />Names may contain characters A-Z, a-"
+"z, 0-9, _ and no spaces<br />Rules may not share the same name as configured "
+"interfaces, members or policies"
+msgstr ""
+
+msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"
+msgstr ""
+
+msgid "Source address"
+msgstr ""
+
+msgid "Source port"
+msgstr ""
+
+msgid "Sticky"
+msgstr ""
+
+msgid "Sticky timeout"
+msgstr ""
+
+msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"
+msgstr ""
+
+msgid "Task"
+msgstr ""
+
+msgid "There are currently %d of %d supported interfaces configured"
+msgstr ""
+
+msgid ""
+"This displays the metric assigned to this interface in /etc/config/network"
+msgstr ""
+
+msgid ""
+"This hostname or IP address will be pinged to determine if the link is up or "
+"down. Leave blank to assume interface is always online"
+msgstr ""
+
+msgid ""
+"This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+">The file is also preserved during sysupgrade.<br /><br />Notes:<br />This "
+"file is interpreted as a shell script.<br />The first line of the script "
+"must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning with # are "
+"comments and are not executed.<br />Put your custom mwan3 action here, they "
+"will<br />be executed with each netifd hotplug interface event<br />on "
+"interfaces for which mwan3 is enabled.<br /><br />There are three main "
+"environment variables that are passed to this script.<br /><br />$ACTION "
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
+
+msgid "Tracking hostname or IP address"
+msgstr ""
+
+msgid "Tracking method"
+msgstr ""
+
+msgid "Tracking reliability"
+msgstr ""
+
+msgid ""
+"Traffic from the same source IP address that previously matched this rule "
+"within the sticky timeout period will use the same WAN interface"
+msgstr ""
+
+msgid "Troubleshooting"
+msgstr ""
+
+msgid ""
+"Use the IP address of this interface as source IP address for traffic "
+"initiated by the router itself"
+msgstr ""
+
+msgid "View the content of /etc/protocols for protocol description"
+msgstr ""
+
+msgid "WARNING: %d interfaces are configured exceeding the maximum of %d!"
+msgstr ""
+
+msgid "WARNING: Interface %s are not found in /etc/config/network"
+msgstr ""
+
+msgid "WARNING: Interface %s has a duplicate metric %s configured"
+msgstr ""
+
+msgid ""
+"WARNING: Interface %s has a higher reliability requirement than tracking "
+"hosts (%d)"
+msgstr ""
+
+msgid "WARNING: Interface %s has no default route in the main routing table"
+msgstr ""
+
+msgid "WARNING: Policy %s has exceeding the maximum name of 15 characters"
+msgstr ""
+
+msgid ""
+"WARNING: Rule %s have a port configured with no or improper protocol "
+"specified!"
+msgstr ""
+
+msgid "Waiting for command to complete..."
+msgstr ""
+
+msgid "Weight"
+msgstr ""
+
+msgid ""
+"When all policy members are offline use this behavior for matched traffic"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "always"
+msgstr ""
+
+msgid "blackhole (drop)"
+msgstr ""
+
+msgid "default (use main routing table)"
+msgstr ""
+
+msgid "ifdown"
+msgstr ""
+
+msgid "ifup"
+msgstr ""
+
+msgid "never"
+msgstr ""
+
+msgid "unreachable (reject)"
+msgstr ""
diff --git a/applications/luci-app-mwan3/po/zh-cn/mwan3.po b/applications/luci-app-mwan3/po/zh-cn/mwan3.po
new file mode 100644
index 0000000000..e730004d97
--- /dev/null
+++ b/applications/luci-app-mwan3/po/zh-cn/mwan3.po
@@ -0,0 +1,769 @@
+#
+# Yangfl <mmyangfl@gmail.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Last-Translator: Yangfl <mmyangfl@gmail.com>\n"
+"Language-Team: <debian-l10n-chinese@lists.debian.org>\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"PO-Revision-Date: 2017-10-28 16:58+0800\n"
+"X-Generator: Gtranslator 2.91.7\n"
+
+msgid "%d hour"
+msgstr "%d 小时"
+
+msgid "%d minute"
+msgstr "%d 分钟"
+
+msgid "%d minutes"
+msgstr "%d 分钟"
+
+msgid "%d second"
+msgstr "%d 秒"
+
+msgid "%d seconds"
+msgstr "%d 秒"
+
+msgid ""
+"Acceptable values: 1-100. This many Tracking IP addresses must respond for "
+"the link to be deemed up"
+msgstr ""
+"取值范围:1-100。这个设置项指定了当多少个 IP 地址能够连通时接口会被认为在线"
+
+msgid "Acceptable values: 1-1000. Defaults to 1 if not set"
+msgstr "取值范围:1-1000。如果不填写,默认值为 1"
+
+msgid "Acceptable values: 1-256. Defaults to 1 if not set"
+msgstr "取值范围:1-256。如果不填写,默认值为 1"
+
+msgid "Check IP rules"
+msgstr "检查 IP 规则"
+
+msgid "Check link quality"
+msgstr "检查连接数量"
+
+msgid "Check routing table"
+msgstr "检查路由表"
+
+msgid "Collecting data..."
+msgstr "正在收集数据..."
+
+msgid "Destination address"
+msgstr "目标地址"
+
+msgid "Destination port"
+msgstr "目标端口"
+
+msgid "Detail"
+msgstr "详细"
+
+msgid "Diagnostics"
+msgstr "诊断"
+
+msgid "Disabled"
+msgstr "已禁用"
+
+msgid ""
+"Downed interface will be deemed up after this many successful ping tests"
+msgstr "当 Ping 成功次数达到这个数值后,已经被认为离线的接口将会重新上线"
+
+msgid "Enabled"
+msgstr "已启用"
+
+msgid "Enter value in hex, starting with <code>0x</code>"
+msgstr "输入十六进制值,以 <code>0x</code> 开头"
+
+msgid "Execute"
+msgstr "执行"
+
+msgid "Expect interface state on up event"
+msgstr "在 up 事件发生时的预期接口状态"
+
+msgid "Failure interval"
+msgstr "故障检测间隔"
+
+msgid "Firewall mask"
+msgstr "防火墙掩码"
+
+msgid "Flush conntrack table"
+msgstr "刷新连接跟踪表"
+
+msgid "Flush global firewall conntrack table on interface events"
+msgstr "在接口事件触发时刷新全局防火墙连接跟踪表"
+
+msgid "Globals"
+msgstr "全局"
+
+msgid "Hotplug ifdown"
+msgstr "Hotplug ifdown"
+
+msgid "Hotplug ifup"
+msgstr "Hotplug ifup"
+
+msgid "INFO: MWAN not running"
+msgstr "信息:MWAN 没有运行"
+
+msgid "IPset"
+msgstr "IPset"
+
+msgid "IPv4"
+msgstr "IPv4"
+
+msgid "IPv6"
+msgstr "IPv6"
+
+msgid "Initial state"
+msgstr "初始状态"
+
+msgid "Interface"
+msgstr "接口"
+
+msgid "Interface down"
+msgstr "接口离线"
+
+msgid "Interface up"
+msgstr "接口在线"
+
+msgid "Interface will be deemed down after this many failed ping tests"
+msgstr "当 Ping 失败次数达到这个数值后,接口会被认为离线"
+
+msgid "Interfaces"
+msgstr "接口"
+
+msgid "Internet Protocol"
+msgstr "互联网协议"
+
+msgid "Keep failure interval"
+msgstr "保持故障检测间隔"
+
+msgid "Keep ping failure interval during failure state"
+msgstr "在故障状态期间保持的 Ping 故障检测间隔"
+
+msgid "Last resort"
+msgstr "备用成员"
+
+msgid "Load Balancing"
+msgstr "负载均衡"
+
+msgid "Loading"
+msgstr "载入中"
+
+msgid "Local source interface"
+msgstr "本地源接口"
+
+msgid "MWAN - Globals"
+msgstr "MWAN - 全局"
+
+msgid "MWAN - Interfaces"
+msgstr "MWAN - 接口"
+
+msgid "MWAN - Members"
+msgstr "MWAN - 成员"
+
+msgid "MWAN - Notification"
+msgstr "MWAN - 通知"
+
+msgid "MWAN - Policies"
+msgstr "MWAN - 策略"
+
+msgid "MWAN - Rules"
+msgstr "MWAN - 规则"
+
+msgid "MWAN Interface Configuration - %s"
+msgstr "MWAN 接口配置 - %s"
+
+msgid "MWAN Interfaces"
+msgstr "MWAN 接口"
+
+msgid "MWAN Member Configuration - %s"
+msgstr "MWAN 成员配置 - %s"
+
+msgid "MWAN Policy Configuration - %s"
+msgstr "MWAN 策略配置 - %s"
+
+msgid "MWAN Rule Configuration - %s"
+msgstr "MWAN 规则配置 - %s"
+
+msgid "MWAN Status - Detail"
+msgstr "MWAN Status - 详细"
+
+msgid "MWAN Status - Diagnostics"
+msgstr "MWAN Status - 诊断"
+
+msgid "MWAN Status - Troubleshooting"
+msgstr "MWAN Status - 故障排除"
+
+msgid ""
+"MWAN supports up to 252 physical and/or logical interfaces<br />MWAN "
+"requires that all interfaces have a unique metric configured in /etc/config/"
+"network<br />Names must match the interface name found in /etc/config/"
+"network<br />Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br /"
+">Interfaces may not share the same name as configured members, policies or "
+"rules"
+msgstr ""
+"MWAN 支持最多 252 个物理或逻辑接口。<br />MWAN 要求所有接口必须在 /etc/"
+"config/network 中设定唯一的网关跃点。<br />名称必须与 /etc/config/network 中"
+"的接口名称匹配。<br />名称允许包括 A-Z、a-z、0-9、_ 但是不能有空格。<br />接"
+"口不应该与成员、策略、规则中的任意一个设置项使用相同的名称"
+
+msgid "Max packet latency [ms]"
+msgstr "最大数据包延迟 [ms]"
+
+msgid "Max packet loss [%]"
+msgstr "最大数据包丢失率 [%]"
+
+msgid ""
+"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or "
+"as a portrange (eg \"1024:2048\") without quotes"
+msgstr ""
+"可以输入一个或多个端口(例如“22”或者“80,443”)或者是一个端口范围(例"
+"如“1024:2048”)不含引号"
+
+msgid "Member"
+msgstr "成员"
+
+msgid "Member used"
+msgstr "使用的成员"
+
+msgid "Members"
+msgstr "成员"
+
+msgid ""
+"Members are profiles attaching a metric and weight to an MWAN interface<br /"
+">Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />Members "
+"may not share the same name as configured interfaces, policies or rules"
+msgstr ""
+"“成员”用来设置每一个 MWAN 接口的跃点数(即接口优先级)和所占比重。<br />名称"
+"允许包括 A-Z、 a-、0-9、_ 但是不能有空格。<br />成员不应该与接口、策略、规则"
+"中的任意一个设置项使用相同的名称"
+
+msgid "Members assigned"
+msgstr "分配的成员"
+
+msgid "Metric"
+msgstr "跃点数"
+
+msgid "Min packet latency [ms]"
+msgstr "最小数据包延迟 [ms]"
+
+msgid "Min packet loss [%]"
+msgstr "最小数据包丢失率 [%]"
+
+msgid ""
+"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/"
+"youtube.com/youtube\")"
+msgstr ""
+"匹配 IPset 规则列表名称。需要先配置 /etc/dnsmasq.conf 中的 IPset 规则(例"
+"如:“ipset=/youtube.com/youtube”)"
+
+msgid "No"
+msgstr "否"
+
+msgid "No MWAN interfaces found"
+msgstr "没有找到 MWAN 接口"
+
+msgid "Notification"
+msgstr "通知"
+
+msgid "Offline"
+msgstr "离线"
+
+msgid "Online"
+msgstr "在线"
+
+msgid "Ping count"
+msgstr "Ping 计数"
+
+msgid "Ping default gateway"
+msgstr "Ping 默认网关"
+
+msgid "Ping interval"
+msgstr "Ping 间隔"
+
+msgid "Ping interval during failure detection"
+msgstr "故障检测期间的 Ping 间隔"
+
+msgid "Ping interval during failure recovering"
+msgstr "故障恢复期间的 Ping 间隔"
+
+msgid "Ping size"
+msgstr "Ping 大小"
+
+msgid "Ping timeout"
+msgstr "Ping 超时"
+
+msgid "Ping tracking IP"
+msgstr "Ping 跟踪 IP"
+
+msgid "Policies"
+msgstr "策略"
+
+msgid ""
+"Policies are profiles grouping one or more members controlling how MWAN "
+"distributes traffic<br />Member interfaces with lower metrics are used "
+"first<br />Member interfaces with the same metric will be load-balanced<br /"
+">Load-balanced member interfaces distribute more traffic out those with "
+"higher weights<br />Names may contain characters A-Z, a-z, 0-9, _ and no "
+"spaces<br />Names must be 15 characters or less<br />Policies may not share "
+"the same name as configured interfaces, members or rules"
+msgstr ""
+"“策略”把成员进行分组,告诉 MWAN 如何分配“规则”中使用这一策略的流量<br />拥有"
+"较低跃点数的成员将会被优先使用。拥有相同跃点数的成员把流量进行负载均衡。<br /"
+">进行负载均衡的成员之间拥有较高比重的成员将会被分配到更多流量。<br />名称允许"
+"包括 A-Z、a-z、0-9、_ 但是不能有空格。名称应该在 15 个字符以内<br />策略不应"
+"该与接口、成员、规则中的任意一个设置项使用相同的名称"
+
+msgid "Policy"
+msgstr "策略"
+
+msgid "Policy assigned"
+msgstr "分配的策略"
+
+msgid "Protocol"
+msgstr "通信协议"
+
+msgid "Recovery interval"
+msgstr "故障恢复间隔"
+
+msgid "Rule"
+msgstr "规则"
+
+msgid "Rules"
+msgstr "规则"
+
+msgid ""
+"Rules specify which traffic will use a particular MWAN policy<br />Rules are "
+"based on IP address, port or protocol<br />Rules are matched from top to "
+"bottom<br />Rules below a matching rule are ignored<br />Traffic not "
+"matching any rule is routed using the main routing table<br />Traffic "
+"destined for known (other than default) networks is handled by the main "
+"routing table<br />Traffic matching a rule, but all WAN interfaces for that "
+"policy are down will be blackholed<br />Names may contain characters A-Z, a-"
+"z, 0-9, _ and no spaces<br />Rules may not share the same name as configured "
+"interfaces, members or policies"
+msgstr ""
+"规则指定哪些流量将使用特定的 MWAN 策略<br />规则基于 IP 地址,端口或协议<br /"
+">规则从上到下匹配<br />匹配规则以下的规则被忽略<br />不符合任何规则的流量将使"
+"用主路由表进行路由<br />目的地为已知(非默认)网络的流量由主路由表处理<br />"
+"流量符合规则,但该策略的所有 WAN 接口关闭后都会被失效<br />名称可包含字符 A-"
+"Z,a-z,0-9,_和空格<br />规则不能与配置的接口、成员或策略共享相同的名称"
+
+msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"
+msgstr "单位为秒。接受的值:1-1000000。留空则使用默认值 600 秒"
+
+msgid "Source address"
+msgstr "源地址"
+
+msgid "Source port"
+msgstr "源端口"
+
+msgid "Sticky"
+msgstr "粘滞模式"
+
+msgid "Sticky timeout"
+msgstr "粘滞超时"
+
+msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"
+msgstr "支持 CIDR 记法(例如:\"192.168.100.0/24\")不含引号"
+
+msgid "Task"
+msgstr "任务"
+
+msgid "There are currently %d of %d supported interfaces configured"
+msgstr "当前已配置 %d 个接口,最大支持 %d 个"
+
+msgid ""
+"This displays the metric assigned to this interface in /etc/config/network"
+msgstr "这里显示了这个接口在 /etc/config/network 中配置的跃点数"
+
+msgid ""
+"This hostname or IP address will be pinged to determine if the link is up or "
+"down. Leave blank to assume interface is always online"
+msgstr "通过 ping 此主机或 IP 地址来确定链路是否在线。留空则认为接口始终在线"
+
+msgid ""
+"This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+">The file is also preserved during sysupgrade.<br /><br />Notes:<br />This "
+"file is interpreted as a shell script.<br />The first line of the script "
+"must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning with # are "
+"comments and are not executed.<br />Put your custom mwan3 action here, they "
+"will<br />be executed with each netifd hotplug interface event<br />on "
+"interfaces for which mwan3 is enabled.<br /><br />There are three main "
+"environment variables that are passed to this script.<br /><br />$ACTION "
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
+"这里允许您修改“/etc/mwan3.user”的内容。<br />该文件在 sysupgrade 期间也会保"
+"留。<br /><br />注意:<br />该文件会作为 shell 脚本解释。<br />脚本的第一行必"
+"须是 &#34;#!/bin/sh&#34;,不带引号。<br />以 # 开头的行是注释,不会执行。"
+"<br />将您的自定义 mwan3 动作放在这里,他们将<br />在启用 mwan3 的接口上<br /"
+">在 netifd hotplug 接口事件时执行。<br /><br />有三个主要的环境变量传递给这个"
+"脚本。<br /><br />$ACTION “ifup” 或 “ifdown”<br />$INTERFACE 启动或停止的接口"
+"名(例如 “wan” 或 “wwan”)<br />$DEVICE 启动或停止接口的物理设备名(例如 "
+"“eth0” 或 “wwan0”)<br /><br />"
+
+msgid "Tracking hostname or IP address"
+msgstr "跟踪的主机或 IP 地址"
+
+msgid "Tracking method"
+msgstr "跟踪方式"
+
+msgid "Tracking reliability"
+msgstr "跟踪可靠性"
+
+msgid ""
+"Traffic from the same source IP address that previously matched this rule "
+"within the sticky timeout period will use the same WAN interface"
+msgstr ""
+"来自相同源 IP 的流量,如果已经匹配过此规则并且在粘滞超时时间内,将会使用相同"
+"的 WAN 接口"
+
+msgid "Troubleshooting"
+msgstr "故障排除"
+
+msgid ""
+"Use the IP address of this interface as source IP address for traffic "
+"initiated by the router itself"
+msgstr "使用该接口的 IP 地址作为路由器本身发起的流量的源 IP 地址"
+
+msgid "View the content of /etc/protocols for protocol description"
+msgstr "查看协议描述的 /etc/protocols 的内容"
+
+msgid "WARNING: %d interfaces are configured exceeding the maximum of %d!"
+msgstr "警告:已配置 %d 个接口,超过最大值 %d!"
+
+msgid "WARNING: Interface %s are not found in /etc/config/network"
+msgstr "警告:接口 %s 在 /etc/config/network 中未找到"
+
+msgid "WARNING: Interface %s has a duplicate metric %s configured"
+msgstr "警告:接口 %s 的 metric %s 配置重复"
+
+msgid ""
+"WARNING: Interface %s has a higher reliability requirement than tracking "
+"hosts (%d)"
+msgstr "警告:接口 %s 比跟踪主机具有更高的可靠性要求(%d)"
+
+msgid "WARNING: Interface %s has no default route in the main routing table"
+msgstr "警告:接口 %s 在主路由表中没有默认的路由"
+
+msgid "WARNING: Policy %s has exceeding the maximum name of 15 characters"
+msgstr "警告:策略 %s 名称超过 15 个字符"
+
+msgid ""
+"WARNING: Rule %s have a port configured with no or improper protocol "
+"specified!"
+msgstr "警告:规则 %s 有一个端口配置没有指定或协议不正确!"
+
+msgid "Waiting for command to complete..."
+msgstr "正在等待命令完成..."
+
+msgid "Weight"
+msgstr "比重"
+
+msgid ""
+"When all policy members are offline use this behavior for matched traffic"
+msgstr "当所有策略成员都无法使用的时候,对使用该策略的流量使用这个操作"
+
+msgid "Yes"
+msgstr "是"
+
+msgid "always"
+msgstr "总是"
+
+msgid "blackhole (drop)"
+msgstr "黑洞(丢弃)"
+
+msgid "default (use main routing table)"
+msgstr "默认(使用主路由表)"
+
+msgid "ifdown"
+msgstr "ifdown"
+
+msgid "ifup"
+msgstr "ifup"
+
+msgid "never"
+msgstr "从不"
+
+msgid "unreachable (reject)"
+msgstr "不可达(拒绝)"
+
+#~ msgid "Online (tracking active)"
+#~ msgstr "在线(跟踪启用中)"
+
+#~ msgid "MWAN Interface Live Status"
+#~ msgstr "MWAN 接口实时状态"
+
+#~ msgid "Online (tracking off)"
+#~ msgstr "在线(跟踪已关闭)"
+
+#~ msgid ""
+#~ "This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+#~ ">The file is also preserved during sysupgrade.<br /><br />Notes:<br /"
+#~ ">This file is interpreted as a shell script.<br />The first line of the "
+#~ "script must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning "
+#~ "with # are comments and are not executed.<br />Put your custom mwan3 "
+#~ "action here, they will<br />be executed with each netifd hotplug "
+#~ "interface event<br />on interfaces for which mwan3 is enabled.<br /><br /"
+#~ ">There are three main environment variables that are passed to this "
+#~ "script.<br /><br />$ACTION Either \"ifup\" or \"ifdown\"<br />$INTERFACE "
+#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan"
+#~ "\")<br />$DEVICE Physical device name which interface went up or down (e."
+#~ "g. \"eth0\" or \"wwan0\")<br /><br />"
+#~ msgstr ""
+#~ "这里允许您修改“/etc/mwan3.user”的内容。<br />该文件在 sysupgrade 期间也会"
+#~ "保留。<br /><br />注意:<br />该文件会作为 shell 脚本解释。<br />脚本的第"
+#~ "一行必须是&#34;#!/bin/sh&#34;,不带引号。<br />以#开头的行是注释,不会执"
+#~ "行。<br />将您的自定义 mwan3 动作放在这里,他们将<br />在启用 mwan3 的接口"
+#~ "上<br />在 netifd hotplug 接口事件时执行。<br /><br />有三个主要的环境变量"
+#~ "传递给这个脚本。<br /><br />$ACTION “ifup”或“ifdown”<br />$INTERFACE 启动"
+#~ "或停止的接口名(例如“wan”或“wwan”)<br />$DEVICE 启动或停止接口的物理设备"
+#~ "名(例如“eth0”或“wwan0”)<br /><br />"
+
+#~ msgid "Currently Configured Interfaces"
+#~ msgstr "当前配置的接口"
+
+#~ msgid "Currently Configured Members"
+#~ msgstr "当前配置的成员"
+
+#~ msgid "Currently Configured Policies"
+#~ msgstr "当前配置的策略"
+
+#~ msgid "Detailed Status"
+#~ msgstr "详细状态"
+
+#~ msgid "Diagnostic Results"
+#~ msgstr "诊断结果"
+
+#~ msgid "Error collecting troubleshooting information"
+#~ msgstr "收集故障排除信息时出错"
+
+#~ msgid "Errors"
+#~ msgstr "错误"
+
+#~ msgid "Globals mwan3 options"
+#~ msgstr "全局 mwan3 选项"
+
+#~ msgid "Interface Status"
+#~ msgstr "接口状态"
+
+#~ msgid "Last 50 MWAN systemlog entries. Newest entries sorted at the top :"
+#~ msgstr "最近 50 条 MWAN 系统日志,最新条目排在顶部:"
+
+#~ msgid "MWAN Detailed Status"
+#~ msgstr "MWAN 详细状态"
+
+#~ msgid "MWAN Interface Configuration"
+#~ msgstr "MWAN 接口配置"
+
+#~ msgid "MWAN Interface Diagnostics"
+#~ msgstr "MWAN 接口诊断"
+
+#~ msgid "MWAN Interface Systemlog"
+#~ msgstr "MWAN 接口系统日志"
+
+#~ msgid "MWAN Member Configuration"
+#~ msgstr "MWAN 成员配置"
+
+#~ msgid "MWAN Policy Configuration"
+#~ msgstr "MWAN 策略配置"
+
+#~ msgid "MWAN Rule Configuration"
+#~ msgstr "MWAN 规则配置"
+
+#~ msgid "MWAN Service Control"
+#~ msgstr "MWAN 服务控制"
+
+#~ msgid "No MWAN systemlog history found"
+#~ msgstr "没有在系统日志中找到 MWAN 历史信息"
+
+#~ msgid "No detailed status information available"
+#~ msgstr "没有状态详细信息可用"
+
+#~ msgid "No diagnostic results returned"
+#~ msgstr "没有返回诊断结果"
+
+#~ msgid "No protocol specified"
+#~ msgstr "未指定协议"
+
+#~ msgid "Restart MWAN"
+#~ msgstr "重启 MWAN"
+
+#~ msgid ""
+#~ "Rules specify which traffic will use a particular MWAN policy based on IP "
+#~ "address, port or protocol<br />Rules are matched from top to bottom. "
+#~ "Rules below a matching rule are ignored. Traffic not matching any rule is "
+#~ "routed using the main routing table<br />Traffic destined for known "
+#~ "(other than default) networks is handled by the main routing table. "
+#~ "Traffic matching a rule, but all WAN interfaces for that policy are down "
+#~ "will be blackholed<br />Names may contain characters A-Z, a-z, 0-9, _ and "
+#~ "no spaces<br />Rules may not share the same name as configured "
+#~ "interfaces, members or policies"
+#~ msgstr ""
+#~ "“规则”基于 IP 地址、协议、端口把流量划分到指定的“策略”中。<br />规则按照从"
+#~ "上到下的顺序进行匹配。除了第一条能够匹配一次通信的规则以外,其它规则将被忽"
+#~ "略。不匹配任何规则的通信将会由系统默认路由表进行。<br />来自已知的网络的转"
+#~ "发流量由系统默认路由表接手,然后 MWAN 从中匹配出相应的流量并转移到 MWAN 自"
+#~ "己的路由表。但是所有被划分到一个无法使用的策略的流量将会无法正常进行路由。"
+#~ "<br />名称允许包括A-Z、a-z、0-9、_ 但是不能有空格。<br />规则不应该与接"
+#~ "口、成员、策略中的任意一个设置项使用相同的名称"
+
+#~ msgid "Start MWAN"
+#~ msgstr "启动 MWAN"
+
+#~ msgid "Stop MWAN"
+#~ msgstr "停止 MWAN"
+
+#~ msgid "Tracking IP"
+#~ msgstr "跟踪的 IP"
+
+#~ msgid "Traffic Rules"
+#~ msgstr "流量规则"
+
+#~ msgid "Troubleshooting Data"
+#~ msgstr "故障排除数据"
+
+#~ msgid "View the contents of /etc/protocols for protocol descriptions"
+#~ msgstr "请查看 /etc/protocols 获取可选协议详情"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces are configured incorrectly or not at all in /etc/"
+#~ "config/network!"
+#~ msgstr "警告:某些接口配置不正确或未配置到 /etc/config/network!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have a higher reliability requirement than there "
+#~ "are tracking IP addresses!"
+#~ msgstr "警告:某些接口的跟踪可靠性要求大于了跟踪 IP 地址总数!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have duplicate metrics configured in /etc/config/"
+#~ "network!"
+#~ msgstr "警告:某些接口在 /etc/config/network 中配置了相同的跃点数!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have no default route in the main routing table!"
+#~ msgstr "警告:某些接口在主路由表中没有默认路由!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have no metric configured in /etc/config/network!"
+#~ msgstr "警告:某些接口没有在 /etc/config/network 中配置跃点数!"
+
+#~ msgid ""
+#~ "WARNING: Some policies have names exceeding the maximum of 15 characters!"
+#~ msgstr "警告:某些策略的名称超过了 15 个字符!"
+
+#~ msgid ""
+#~ "WARNING: Some rules have a port configured with no or improper protocol "
+#~ "specified! Please configure a specific protocol!"
+#~ msgstr ""
+#~ "警告:某些规则指定了端口却没有配置或配置了不正确的协议,请重新指定协议!"
+
+#~ msgid ""
+#~ "WARNING: This and other interfaces have duplicate metrics configured in /"
+#~ "etc/config/network!"
+#~ msgstr "警告:此接口和其他接口在 /etc/config/network 中配置了相同的跃点数!"
+
+#~ msgid ""
+#~ "WARNING: This interface has a higher reliability requirement than there "
+#~ "are tracking IP addresses!"
+#~ msgstr "警告:此接口的跟踪可靠性要求大于了跟踪 IP 地址总数!"
+
+#~ msgid ""
+#~ "WARNING: This interface has no default route in the main routing table!"
+#~ msgstr "警告:此接口在主路由表中没有默认路由!"
+
+#~ msgid ""
+#~ "WARNING: This interface has no metric configured in /etc/config/network!"
+#~ msgstr "警告:此接口没有在 /etc/config/network 中配置跃点数!"
+
+#~ msgid ""
+#~ "WARNING: This interface is configured incorrectly or not at all in /etc/"
+#~ "config/network!"
+#~ msgstr "警告:此接口配置不正确或未配置到 /etc/config/network!"
+
+#~ msgid ""
+#~ "WARNING: This policy's name is %d characters exceeding the maximum of 15!"
+#~ msgstr "警告:此策略的名称具有 %d 个字符,超过了 15 个字符!"
+
+#~ msgid ""
+#~ "WARNING: This rule is incorrectly configured with no or improper protocol "
+#~ "specified! Please configure a specific protocol!"
+#~ msgstr "警告:此规则没有配置或配置了不正确的协议,请重新指定协议!"
+
+#~ msgid "Waiting for MWAN to %s..."
+#~ msgstr "等待 MWAN %s..."
+
+#~ msgid "Waiting for diagnostic results..."
+#~ msgstr "等待诊断结果..."
+
+#~ msgid "restart"
+#~ msgstr "重启"
+
+#~ msgid "start"
+#~ msgstr "启动"
+
+#~ msgid "stop"
+#~ msgstr "停止"
+
+#~ msgid "Advanced"
+#~ msgstr "高级"
+
+#~ msgid "Configuration"
+#~ msgstr "配置"
+
+#~ msgid "Hotplug Script"
+#~ msgstr "Hotplug 脚本"
+
+#~ msgid "MWAN Config"
+#~ msgstr "MWAN 配置文件"
+
+#~ msgid "Network Config"
+#~ msgstr "网络配置文件"
+
+#~ msgid "Overview"
+#~ msgstr "概况"
+
+#~ msgid "This section allows you to modify the contents of /etc/config/mwan3"
+#~ msgstr "这里允许您修改 /etc/config/mwan3 的内容"
+
+#~ msgid ""
+#~ "This section allows you to modify the contents of /etc/config/network"
+#~ msgstr "这里允许您修改 /etc/config/network 的内容"
+
+#~ msgid ""
+#~ "This section allows you to modify the contents of /etc/config/wireless"
+#~ msgstr "这里允许您修改 /etc/config/wireless 的内容"
+
+#~ msgid "Wireless Config"
+#~ msgstr "无线配置"
+
+#~ msgid "Restore default hotplug script"
+#~ msgstr "恢复默认的 hotplug 脚本"
+
+#~ msgid "Restore..."
+#~ msgstr "恢复..."
+
+#~ msgid ""
+#~ "This section allows you to modify the contents of /etc/hotplug.d/iface/16-"
+#~ "mwancustom<br />This is useful for running system commands and/or scripts "
+#~ "based on interface ifup or ifdown hotplug events<br /><br />Notes:<br /"
+#~ ">The first line of the script must be &#34;#!/bin/sh&#34; without "
+#~ "quotes<br />Lines beginning with # are comments and are not executed<br /"
+#~ "><br />Available variables:<br />$ACTION is the hotplug event (ifup, "
+#~ "ifdown)<br />$INTERFACE is the interface name (wan1, wan2, etc.)<br />"
+#~ "$DEVICE is the device name attached to the interface (eth0.1, eth1, etc.)"
+#~ msgstr ""
+#~ "这里允许您修改 /etc/hotplug.d/iface/16-mwancustom 的内容<br />这可以在接"
+#~ "口 ifup 或 ifdown Hotplug 事件时运行系统命令或脚本<br /><br />注意:<br />"
+#~ "脚本的第一行必须是 &#34;#!/bin/sh&#34; 不含引号<br />以#开头的行是注释,"
+#~ "不会执行<br /><br />可用变量:<br />$ACTION 是 Hotplug 事件(ifup, ifdown)"
+#~ "<br />$INTERFACE 是接口名称(wan1、wan2 等)<br />$DEVICE 是连接到接口的设"
+#~ "备名称 (eth0.1、eth1 等)"
diff --git a/applications/luci-app-mwan3/po/zh-tw/mwan3.po b/applications/luci-app-mwan3/po/zh-tw/mwan3.po
new file mode 100644
index 0000000000..9fa5263428
--- /dev/null
+++ b/applications/luci-app-mwan3/po/zh-tw/mwan3.po
@@ -0,0 +1,756 @@
+#
+# Yangfl <mmyangfl@gmail.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Last-Translator: Yangfl <mmyangfl@gmail.com>\n"
+"Language-Team: <debian-l10n-chinese@lists.debian.org>\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"PO-Revision-Date: 2017-10-28 16:58+0800\n"
+"X-Generator: Gtranslator 2.91.7\n"
+
+msgid "%d hour"
+msgstr "%d 小時"
+
+msgid "%d minute"
+msgstr "%d 分鐘"
+
+msgid "%d minutes"
+msgstr "%d 分鐘"
+
+msgid "%d second"
+msgstr "%d 秒"
+
+msgid "%d seconds"
+msgstr "%d 秒"
+
+msgid ""
+"Acceptable values: 1-100. This many Tracking IP addresses must respond for "
+"the link to be deemed up"
+msgstr ""
+"取值範圍:1-100。這個設定項指定了當多少個 IP 位址能夠連通時介面會被認為線上"
+
+msgid "Acceptable values: 1-1000. Defaults to 1 if not set"
+msgstr "取值範圍:1-1000。如果不填寫,預設值為 1"
+
+msgid "Acceptable values: 1-256. Defaults to 1 if not set"
+msgstr "取值範圍:1-256。如果不填寫,預設值為 1"
+
+msgid "Check IP rules"
+msgstr "檢查 IP 規則"
+
+msgid "Check link quality"
+msgstr ""
+
+msgid "Check routing table"
+msgstr "檢查路由表"
+
+msgid "Collecting data..."
+msgstr "正在收集資料..."
+
+msgid "Destination address"
+msgstr "目標位址"
+
+msgid "Destination port"
+msgstr "目標埠"
+
+msgid "Detail"
+msgstr ""
+
+msgid "Diagnostics"
+msgstr "診斷"
+
+msgid "Disabled"
+msgstr "已禁用"
+
+msgid ""
+"Downed interface will be deemed up after this many successful ping tests"
+msgstr "當 Ping 成功次數達到這個數值後,已經被認為離線的介面將會重新上線"
+
+msgid "Enabled"
+msgstr "已啟用"
+
+msgid "Enter value in hex, starting with <code>0x</code>"
+msgstr "輸入十六進位制值,以 <code>0x</code> 開頭"
+
+msgid "Execute"
+msgstr ""
+
+msgid "Expect interface state on up event"
+msgstr "在 up 事件發生時的預期介面狀態"
+
+msgid "Failure interval"
+msgstr "故障檢測間隔"
+
+msgid "Firewall mask"
+msgstr "防火牆掩碼"
+
+msgid "Flush conntrack table"
+msgstr "重新整理連線跟蹤表"
+
+msgid "Flush global firewall conntrack table on interface events"
+msgstr "在介面事件觸發時重新整理全域性防火牆連線跟蹤表"
+
+msgid "Globals"
+msgstr "全域性"
+
+msgid "Hotplug ifdown"
+msgstr "Hotplug ifdown"
+
+msgid "Hotplug ifup"
+msgstr "Hotplug ifup"
+
+msgid "INFO: MWAN not running"
+msgstr ""
+
+msgid "IPset"
+msgstr "IPset"
+
+msgid "IPv4"
+msgstr "IPv4"
+
+msgid "IPv6"
+msgstr "IPv6"
+
+msgid "Initial state"
+msgstr "初始狀態"
+
+msgid "Interface"
+msgstr "介面"
+
+msgid "Interface down"
+msgstr "介面離線"
+
+msgid "Interface up"
+msgstr "介面線上"
+
+msgid "Interface will be deemed down after this many failed ping tests"
+msgstr "當 Ping 失敗次數達到這個數值後,介面會被認為離線"
+
+msgid "Interfaces"
+msgstr "介面"
+
+msgid "Internet Protocol"
+msgstr "網際網路協議"
+
+msgid "Keep failure interval"
+msgstr "保持故障檢測間隔"
+
+msgid "Keep ping failure interval during failure state"
+msgstr "在故障狀態期間保持的 Ping 故障檢測間隔"
+
+msgid "Last resort"
+msgstr "備用成員"
+
+msgid "Load Balancing"
+msgstr "負載均衡"
+
+msgid "Loading"
+msgstr "載入中"
+
+msgid "Local source interface"
+msgstr "本地源介面"
+
+msgid "MWAN - Globals"
+msgstr ""
+
+msgid "MWAN - Interfaces"
+msgstr ""
+
+msgid "MWAN - Members"
+msgstr ""
+
+msgid "MWAN - Notification"
+msgstr ""
+
+msgid "MWAN - Policies"
+msgstr ""
+
+msgid "MWAN - Rules"
+msgstr ""
+
+msgid "MWAN Interface Configuration - %s"
+msgstr "MWAN 介面配置 - %s"
+
+msgid "MWAN Interfaces"
+msgstr ""
+
+msgid "MWAN Member Configuration - %s"
+msgstr "MWAN 成員配置 - %s"
+
+msgid "MWAN Policy Configuration - %s"
+msgstr "MWAN 策略配置 - %s"
+
+msgid "MWAN Rule Configuration - %s"
+msgstr "MWAN 規則配置 - %s"
+
+msgid "MWAN Status - Detail"
+msgstr ""
+
+msgid "MWAN Status - Diagnostics"
+msgstr ""
+
+msgid "MWAN Status - Troubleshooting"
+msgstr ""
+
+msgid ""
+"MWAN supports up to 252 physical and/or logical interfaces<br />MWAN "
+"requires that all interfaces have a unique metric configured in /etc/config/"
+"network<br />Names must match the interface name found in /etc/config/"
+"network<br />Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br /"
+">Interfaces may not share the same name as configured members, policies or "
+"rules"
+msgstr ""
+"MWAN 支援最多 252 個物理或邏輯介面。<br />MWAN 要求所有介面必須在 /etc/"
+"config/network 中設定唯一的閘道器躍點。<br />名稱必須與 /etc/config/network "
+"中的介面名稱匹配。<br />名稱允許包括 A-Z、a-z、0-9、_ 但是不能有空格。<br />"
+"介面不應該與成員、策略、規則中的任意一個設定項使用相同的名稱"
+
+msgid "Max packet latency [ms]"
+msgstr ""
+
+msgid "Max packet loss [%]"
+msgstr ""
+
+msgid ""
+"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or "
+"as a portrange (eg \"1024:2048\") without quotes"
+msgstr ""
+"可以輸入一個或多個埠(例如“22”或者“80,443”)或者是一個埠範圍(例"
+"如“1024:2048”)不含引號"
+
+msgid "Member"
+msgstr "成員"
+
+msgid "Member used"
+msgstr "使用的成員"
+
+msgid "Members"
+msgstr "成員"
+
+msgid ""
+"Members are profiles attaching a metric and weight to an MWAN interface<br /"
+">Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />Members "
+"may not share the same name as configured interfaces, policies or rules"
+msgstr ""
+"“成員”用來設定每一個 MWAN 介面的躍點數(即介面優先順序)和所佔比重。<br />名"
+"稱允許包括 A-Z、 a-、0-9、_ 但是不能有空格。<br />成員不應該與介面、策略、規"
+"則中的任意一個設定項使用相同的名稱"
+
+msgid "Members assigned"
+msgstr "分配的成員"
+
+msgid "Metric"
+msgstr "躍點數"
+
+msgid "Min packet latency [ms]"
+msgstr ""
+
+msgid "Min packet loss [%]"
+msgstr ""
+
+msgid ""
+"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/"
+"youtube.com/youtube\")"
+msgstr ""
+"匹配 IPset 規則列表名稱。需要先配置 /etc/dnsmasq.conf 中的 IPset 規則(例"
+"如:“ipset=/youtube.com/youtube”)"
+
+msgid "No"
+msgstr "否"
+
+msgid "No MWAN interfaces found"
+msgstr "沒有找到 MWAN 介面"
+
+msgid "Notification"
+msgstr ""
+
+msgid "Offline"
+msgstr "離線"
+
+msgid "Online"
+msgstr "線上"
+
+msgid "Ping count"
+msgstr "Ping 計數"
+
+msgid "Ping default gateway"
+msgstr "Ping 預設閘道器"
+
+msgid "Ping interval"
+msgstr "Ping 間隔"
+
+msgid "Ping interval during failure detection"
+msgstr "故障檢測期間的 Ping 間隔"
+
+msgid "Ping interval during failure recovering"
+msgstr "故障恢復期間的 Ping 間隔"
+
+msgid "Ping size"
+msgstr "Ping 大小"
+
+msgid "Ping timeout"
+msgstr "Ping 超時"
+
+msgid "Ping tracking IP"
+msgstr "Ping 跟蹤 IP"
+
+msgid "Policies"
+msgstr "策略"
+
+msgid ""
+"Policies are profiles grouping one or more members controlling how MWAN "
+"distributes traffic<br />Member interfaces with lower metrics are used "
+"first<br />Member interfaces with the same metric will be load-balanced<br /"
+">Load-balanced member interfaces distribute more traffic out those with "
+"higher weights<br />Names may contain characters A-Z, a-z, 0-9, _ and no "
+"spaces<br />Names must be 15 characters or less<br />Policies may not share "
+"the same name as configured interfaces, members or rules"
+msgstr ""
+"“策略”把成員進行分組,告訴 MWAN 如何分配“規則”中使用這一策略的流量<br />擁有"
+"較低躍點數的成員將會被優先使用。擁有相同躍點數的成員把流量進行負載均衡。<br /"
+">進行負載均衡的成員之間擁有較高比重的成員將會被分配到更多流量。<br />名稱允許"
+"包括A-Z、a-z、0-9、_ 但是不能有空格。名稱應該在 15 個字元以內<br />策略不應該"
+"與介面、成員、規則中的任意一個設定項使用相同的名稱"
+
+msgid "Policy"
+msgstr "策略"
+
+msgid "Policy assigned"
+msgstr "分配的策略"
+
+msgid "Protocol"
+msgstr "通訊協議"
+
+msgid "Recovery interval"
+msgstr "故障恢復間隔"
+
+msgid "Rule"
+msgstr "規則"
+
+msgid "Rules"
+msgstr "規則"
+
+msgid ""
+"Rules specify which traffic will use a particular MWAN policy<br />Rules are "
+"based on IP address, port or protocol<br />Rules are matched from top to "
+"bottom<br />Rules below a matching rule are ignored<br />Traffic not "
+"matching any rule is routed using the main routing table<br />Traffic "
+"destined for known (other than default) networks is handled by the main "
+"routing table<br />Traffic matching a rule, but all WAN interfaces for that "
+"policy are down will be blackholed<br />Names may contain characters A-Z, a-"
+"z, 0-9, _ and no spaces<br />Rules may not share the same name as configured "
+"interfaces, members or policies"
+msgstr ""
+
+msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set"
+msgstr "單位為秒。接受的值:1-1000000。留空則使用預設值 600 秒"
+
+msgid "Source address"
+msgstr "源位址"
+
+msgid "Source port"
+msgstr "源埠"
+
+msgid "Sticky"
+msgstr "粘滯模式"
+
+msgid "Sticky timeout"
+msgstr "粘滯超時"
+
+msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes"
+msgstr "支援 CIDR 記法(例如:\"192.168.100.0/24\")不含引號"
+
+msgid "Task"
+msgstr ""
+
+msgid "There are currently %d of %d supported interfaces configured"
+msgstr "當前已配置 %d 個介面,最大支援 %d 個"
+
+msgid ""
+"This displays the metric assigned to this interface in /etc/config/network"
+msgstr "這裡顯示了這個介面在 /etc/config/network 中配置的躍點數"
+
+msgid ""
+"This hostname or IP address will be pinged to determine if the link is up or "
+"down. Leave blank to assume interface is always online"
+msgstr "通過 ping 此主機或 IP 位址來確定鏈路是否線上。留空則認為介面始終線上"
+
+msgid ""
+"This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+">The file is also preserved during sysupgrade.<br /><br />Notes:<br />This "
+"file is interpreted as a shell script.<br />The first line of the script "
+"must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning with # are "
+"comments and are not executed.<br />Put your custom mwan3 action here, they "
+"will<br />be executed with each netifd hotplug interface event<br />on "
+"interfaces for which mwan3 is enabled.<br /><br />There are three main "
+"environment variables that are passed to this script.<br /><br />$ACTION "
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
+
+msgid "Tracking hostname or IP address"
+msgstr "跟蹤的主機或 IP 位址"
+
+msgid "Tracking method"
+msgstr "跟蹤方式"
+
+msgid "Tracking reliability"
+msgstr "跟蹤可靠性"
+
+msgid ""
+"Traffic from the same source IP address that previously matched this rule "
+"within the sticky timeout period will use the same WAN interface"
+msgstr ""
+"來自相同源 IP 的流量,如果已經匹配過此規則並且在粘滯超時時間內,將會使用相同"
+"的 WAN 介面"
+
+msgid "Troubleshooting"
+msgstr "故障排除"
+
+msgid ""
+"Use the IP address of this interface as source IP address for traffic "
+"initiated by the router itself"
+msgstr "使用該介面的 IP 位址作為路由器本身發起的流量的源 IP 位址"
+
+msgid "View the content of /etc/protocols for protocol description"
+msgstr ""
+
+msgid "WARNING: %d interfaces are configured exceeding the maximum of %d!"
+msgstr "警告:已配置 %d 個介面,超過最大值 %d!"
+
+msgid "WARNING: Interface %s are not found in /etc/config/network"
+msgstr ""
+
+msgid "WARNING: Interface %s has a duplicate metric %s configured"
+msgstr ""
+
+msgid ""
+"WARNING: Interface %s has a higher reliability requirement than tracking "
+"hosts (%d)"
+msgstr ""
+
+msgid "WARNING: Interface %s has no default route in the main routing table"
+msgstr ""
+
+msgid "WARNING: Policy %s has exceeding the maximum name of 15 characters"
+msgstr ""
+
+msgid ""
+"WARNING: Rule %s have a port configured with no or improper protocol "
+"specified!"
+msgstr ""
+
+msgid "Waiting for command to complete..."
+msgstr ""
+
+msgid "Weight"
+msgstr "比重"
+
+msgid ""
+"When all policy members are offline use this behavior for matched traffic"
+msgstr "當所有策略成員都無法使用的時候,對使用該策略的流量使用這個操作"
+
+msgid "Yes"
+msgstr "是"
+
+msgid "always"
+msgstr "總是"
+
+msgid "blackhole (drop)"
+msgstr "黑洞(丟棄)"
+
+msgid "default (use main routing table)"
+msgstr "預設(使用主路由表)"
+
+msgid "ifdown"
+msgstr "ifdown"
+
+msgid "ifup"
+msgstr "ifup"
+
+msgid "never"
+msgstr "從不"
+
+msgid "unreachable (reject)"
+msgstr "不可達(拒絕)"
+
+#~ msgid "Online (tracking active)"
+#~ msgstr "線上(跟蹤啟用中)"
+
+#~ msgid "MWAN Interface Live Status"
+#~ msgstr "MWAN 介面實時狀態"
+
+#~ msgid "Online (tracking off)"
+#~ msgstr "線上(跟蹤已關閉)"
+
+#~ msgid ""
+#~ "This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+#~ ">The file is also preserved during sysupgrade.<br /><br />Notes:<br /"
+#~ ">This file is interpreted as a shell script.<br />The first line of the "
+#~ "script must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning "
+#~ "with # are comments and are not executed.<br />Put your custom mwan3 "
+#~ "action here, they will<br />be executed with each netifd hotplug "
+#~ "interface event<br />on interfaces for which mwan3 is enabled.<br /><br /"
+#~ ">There are three main environment variables that are passed to this "
+#~ "script.<br /><br />$ACTION Either \"ifup\" or \"ifdown\"<br />$INTERFACE "
+#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan"
+#~ "\")<br />$DEVICE Physical device name which interface went up or down (e."
+#~ "g. \"eth0\" or \"wwan0\")<br /><br />"
+#~ msgstr ""
+#~ "這裡允許您修改“/etc/mwan3.user”的內容。<br />該檔案在 sysupgrade 期間也會"
+#~ "保留。<br /><br />注意:<br />該檔案會作為 shell 指令碼解釋。<br />指令碼"
+#~ "的第一行必須是&#34;#!/bin/sh&#34;,不帶引號。<br />以#開頭的行是註釋,不會"
+#~ "執行。<br />將您的自定義 mwan3 動作放在這裡,他們將<br />在啟用 mwan3 的介"
+#~ "面上<br />在 netifd hotplug 介面事件時執行。<br /><br />有三個主要的環境變"
+#~ "數傳遞給這個腳本。<br /><br />$ACTION “ifup”或“ifdown”<br />$INTERFACE 啟"
+#~ "動或停止的介面名(例如“wan”或“wwan”)<br />$DEVICE 啟動或停止介面的物理裝"
+#~ "置名(例如“eth0”或“wwan0”)<br /><br />"
+
+#~ msgid "Currently Configured Interfaces"
+#~ msgstr "當前配置的介面"
+
+#~ msgid "Currently Configured Members"
+#~ msgstr "當前配置的成員"
+
+#~ msgid "Currently Configured Policies"
+#~ msgstr "當前配置的策略"
+
+#~ msgid "Detailed Status"
+#~ msgstr "詳細狀態"
+
+#~ msgid "Diagnostic Results"
+#~ msgstr "診斷結果"
+
+#~ msgid "Error collecting troubleshooting information"
+#~ msgstr "收集故障排除資訊時出錯"
+
+#~ msgid "Errors"
+#~ msgstr "錯誤"
+
+#~ msgid "Globals mwan3 options"
+#~ msgstr "全域性 mwan3 選項"
+
+#~ msgid "Interface Status"
+#~ msgstr "介面狀態"
+
+#~ msgid "Last 50 MWAN systemlog entries. Newest entries sorted at the top :"
+#~ msgstr "最近 50 條 MWAN 系統日誌,最新條目排在頂部:"
+
+#~ msgid "MWAN Detailed Status"
+#~ msgstr "MWAN 詳細狀態"
+
+#~ msgid "MWAN Interface Configuration"
+#~ msgstr "MWAN 介面配置"
+
+#~ msgid "MWAN Interface Diagnostics"
+#~ msgstr "MWAN 介面診斷"
+
+#~ msgid "MWAN Interface Systemlog"
+#~ msgstr "MWAN 介面系統日誌"
+
+#~ msgid "MWAN Member Configuration"
+#~ msgstr "MWAN 成員配置"
+
+#~ msgid "MWAN Policy Configuration"
+#~ msgstr "MWAN 策略配置"
+
+#~ msgid "MWAN Rule Configuration"
+#~ msgstr "MWAN 規則配置"
+
+#~ msgid "MWAN Service Control"
+#~ msgstr "MWAN 服務控制"
+
+#~ msgid "No MWAN systemlog history found"
+#~ msgstr "沒有在系統日誌中找到 MWAN 歷史資訊"
+
+#~ msgid "No detailed status information available"
+#~ msgstr "沒有狀態詳細資訊可用"
+
+#~ msgid "No diagnostic results returned"
+#~ msgstr "沒有返回診斷結果"
+
+#~ msgid "No protocol specified"
+#~ msgstr "未指定協議"
+
+#~ msgid "Restart MWAN"
+#~ msgstr "重啟 MWAN"
+
+#~ msgid ""
+#~ "Rules specify which traffic will use a particular MWAN policy based on IP "
+#~ "address, port or protocol<br />Rules are matched from top to bottom. "
+#~ "Rules below a matching rule are ignored. Traffic not matching any rule is "
+#~ "routed using the main routing table<br />Traffic destined for known "
+#~ "(other than default) networks is handled by the main routing table. "
+#~ "Traffic matching a rule, but all WAN interfaces for that policy are down "
+#~ "will be blackholed<br />Names may contain characters A-Z, a-z, 0-9, _ and "
+#~ "no spaces<br />Rules may not share the same name as configured "
+#~ "interfaces, members or policies"
+#~ msgstr ""
+#~ "“規則”基於 IP 位址、協議、埠把流量劃分到指定的“策略”中。<br />規則按照從上"
+#~ "到下的順序進行匹配。除了第一條能夠匹配一次通訊的規則以外,其它規則將被忽"
+#~ "略。不匹配任何規則的通訊將會由系統預設路由表進行。<br />來自已知的網路的轉"
+#~ "發流量由系統預設路由表接手,然後 MWAN 從中匹配出相應的流量並轉移到 MWAN 自"
+#~ "己的路由表。但是所有被劃分到一個無法使用的策略的流量將會無法正常進行路由。"
+#~ "<br />名稱允許包括A-Z、a-z、0-9、_ 但是不能有空格。<br />規則不應該與介"
+#~ "面、成員、策略中的任意一個設定項使用相同的名稱"
+
+#~ msgid "Start MWAN"
+#~ msgstr "啟動 MWAN"
+
+#~ msgid "Stop MWAN"
+#~ msgstr "停止 MWAN"
+
+#~ msgid "Tracking IP"
+#~ msgstr "跟蹤的 IP"
+
+#~ msgid "Traffic Rules"
+#~ msgstr "流量規則"
+
+#~ msgid "Troubleshooting Data"
+#~ msgstr "故障排除資料"
+
+#~ msgid "View the contents of /etc/protocols for protocol descriptions"
+#~ msgstr "請檢視 /etc/protocols 獲取可選協議詳情"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces are configured incorrectly or not at all in /etc/"
+#~ "config/network!"
+#~ msgstr "警告:某些介面配置不正確或未配置到 /etc/config/network!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have a higher reliability requirement than there "
+#~ "are tracking IP addresses!"
+#~ msgstr "警告:某些介面的跟蹤可靠性要求大於了跟蹤 IP 位址總數!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have duplicate metrics configured in /etc/config/"
+#~ "network!"
+#~ msgstr "警告:某些介面在 /etc/config/network 中配置了相同的躍點數!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have no default route in the main routing table!"
+#~ msgstr "警告:某些介面在主路由表中沒有預設路由!"
+
+#~ msgid ""
+#~ "WARNING: Some interfaces have no metric configured in /etc/config/network!"
+#~ msgstr "警告:某些介面沒有在 /etc/config/network 中配置躍點數!"
+
+#~ msgid ""
+#~ "WARNING: Some policies have names exceeding the maximum of 15 characters!"
+#~ msgstr "警告:某些策略的名稱超過了 15 個字元!"
+
+#~ msgid ""
+#~ "WARNING: Some rules have a port configured with no or improper protocol "
+#~ "specified! Please configure a specific protocol!"
+#~ msgstr ""
+#~ "警告:某些規則指定了埠卻沒有配置或配置了不正確的協議,請重新指定協議!"
+
+#~ msgid ""
+#~ "WARNING: This and other interfaces have duplicate metrics configured in /"
+#~ "etc/config/network!"
+#~ msgstr "警告:此介面和其他介面在 /etc/config/network 中配置了相同的躍點數!"
+
+#~ msgid ""
+#~ "WARNING: This interface has a higher reliability requirement than there "
+#~ "are tracking IP addresses!"
+#~ msgstr "警告:此介面的跟蹤可靠性要求大於了跟蹤 IP 位址總數!"
+
+#~ msgid ""
+#~ "WARNING: This interface has no default route in the main routing table!"
+#~ msgstr "警告:此介面在主路由表中沒有預設路由!"
+
+#~ msgid ""
+#~ "WARNING: This interface has no metric configured in /etc/config/network!"
+#~ msgstr "警告:此介面沒有在 /etc/config/network 中配置躍點數!"
+
+#~ msgid ""
+#~ "WARNING: This interface is configured incorrectly or not at all in /etc/"
+#~ "config/network!"
+#~ msgstr "警告:此介面配置不正確或未配置到 /etc/config/network!"
+
+#~ msgid ""
+#~ "WARNING: This policy's name is %d characters exceeding the maximum of 15!"
+#~ msgstr "警告:此策略的名稱具有 %d 個字元,超過了 15 個字元!"
+
+#~ msgid ""
+#~ "WARNING: This rule is incorrectly configured with no or improper protocol "
+#~ "specified! Please configure a specific protocol!"
+#~ msgstr "警告:此規則沒有配置或配置了不正確的協議,請重新指定協議!"
+
+#~ msgid "Waiting for MWAN to %s..."
+#~ msgstr "等待 MWAN %s..."
+
+#~ msgid "Waiting for diagnostic results..."
+#~ msgstr "等待診斷結果..."
+
+#~ msgid "restart"
+#~ msgstr "重啟"
+
+#~ msgid "start"
+#~ msgstr "啟動"
+
+#~ msgid "stop"
+#~ msgstr "停止"
+
+#~ msgid "Advanced"
+#~ msgstr "高階"
+
+#~ msgid "Configuration"
+#~ msgstr "配置"
+
+#~ msgid "Hotplug Script"
+#~ msgstr "Hotplug 指令碼"
+
+#~ msgid "MWAN Config"
+#~ msgstr "MWAN 配置檔案"
+
+#~ msgid "Network Config"
+#~ msgstr "網路配置檔案"
+
+#~ msgid "Overview"
+#~ msgstr "概況"
+
+#~ msgid "This section allows you to modify the contents of /etc/config/mwan3"
+#~ msgstr "這裡允許您修改 /etc/config/mwan3 的內容"
+
+#~ msgid ""
+#~ "This section allows you to modify the contents of /etc/config/network"
+#~ msgstr "這裡允許您修改 /etc/config/network 的內容"
+
+#~ msgid ""
+#~ "This section allows you to modify the contents of /etc/config/wireless"
+#~ msgstr "這裡允許您修改 /etc/config/wireless 的內容"
+
+#~ msgid "Wireless Config"
+#~ msgstr "無線配置"
+
+#~ msgid "Restore default hotplug script"
+#~ msgstr "恢復預設的 hotplug 指令碼"
+
+#~ msgid "Restore..."
+#~ msgstr "恢復..."
+
+#~ msgid ""
+#~ "This section allows you to modify the contents of /etc/hotplug.d/iface/16-"
+#~ "mwancustom<br />This is useful for running system commands and/or scripts "
+#~ "based on interface ifup or ifdown hotplug events<br /><br />Notes:<br /"
+#~ ">The first line of the script must be &#34;#!/bin/sh&#34; without "
+#~ "quotes<br />Lines beginning with # are comments and are not executed<br /"
+#~ "><br />Available variables:<br />$ACTION is the hotplug event (ifup, "
+#~ "ifdown)<br />$INTERFACE is the interface name (wan1, wan2, etc.)<br />"
+#~ "$DEVICE is the device name attached to the interface (eth0.1, eth1, etc.)"
+#~ msgstr ""
+#~ "這裡允許您修改 /etc/hotplug.d/iface/16-mwancustom 的內容<br />這可以在接"
+#~ "口 ifup 或 ifdown Hotplug 事件時執行系統命令或指令碼<br /><br />注意:<br /"
+#~ ">指令碼的第一行必須是 &#34;#!/bin/sh&#34; 不含引號<br />以#開頭的行是註"
+#~ "釋,不會執行<br /><br />可用變數:<br />$ACTION 是 Hotplug 事件(ifup, "
+#~ "ifdown)<br />$INTERFACE 是介面名稱(wan1、wan2 等)<br />$DEVICE 是連線到"
+#~ "介面的設備名稱 (eth0.1、eth1 等)"
diff --git a/applications/luci-app-mwan3/root/etc/uci-defaults/60_luci-mwan3 b/applications/luci-app-mwan3/root/etc/uci-defaults/60_luci-mwan3
new file mode 100755
index 0000000000..150ea5a3f1
--- /dev/null
+++ b/applications/luci-app-mwan3/root/etc/uci-defaults/60_luci-mwan3
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# replace existing mwan ucitrack entry
+uci -q batch <<-EOF >/dev/null
+ del ucitrack.@mwan3[-1]
+ add ucitrack mwan3
+ set ucitrack.@mwan3[-1].exec="/etc/init.d/mwan3 reload"
+ commit ucitrack
+EOF
+
+uci -q get mwan3.globals >/dev/null || {
+ uci -q add mwan3 globals >/dev/null
+ uci -q rename mwan3.@globals[-1]="globals" >/dev/null
+ uci -q set mwan3.globals.local_source="none" >/dev/null
+ uci commit mwan3
+}
+
+# remove LuCI cache
+rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
+
+exit 0