From 4165bdc931d8968c0e220d20f4d22250805d1224 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Sun, 14 Oct 2018 00:53:11 +0800 Subject: [PATCH] re-add luci syncdial and make fullcone support for mwan3 --- package/lean/luci-app-mwan3-alt/Makefile | 19 + .../luasrc/controller/mwan3.lua | 320 +++++ .../luasrc/model/cbi/mwan/globalsconfig.lua | 31 + .../luasrc/model/cbi/mwan/interface.lua | 240 ++++ .../luasrc/model/cbi/mwan/interfaceconfig.lua | 240 ++++ .../luasrc/model/cbi/mwan/member.lua | 44 + .../luasrc/model/cbi/mwan/memberconfig.lua | 31 + .../luasrc/model/cbi/mwan/notify.lua | 45 + .../luasrc/model/cbi/mwan/policy.lua | 87 ++ .../luasrc/model/cbi/mwan/policyconfig.lua | 30 + .../luasrc/model/cbi/mwan/rule.lua | 104 ++ .../luasrc/model/cbi/mwan/ruleconfig.lua | 63 + .../luasrc/view/admin_status/index/mwan.htm | 3 + .../view/mwan/overview_status_interface.htm | 75 ++ .../luasrc/view/mwan/status_detail.htm | 39 + .../luasrc/view/mwan/status_diagnostics.htm | 90 ++ .../luasrc/view/mwan/status_interface.htm | 20 + .../view/mwan/status_troubleshooting.htm | 39 + .../lean/luci-app-mwan3-alt/po/de/mwan3.po | 505 ++++++++ .../lean/luci-app-mwan3-alt/po/ja/mwan3.po | 563 +++++++++ .../lean/luci-app-mwan3-alt/po/ru/mwan3.po | 592 ++++++++++ .../luci-app-mwan3-alt/po/templates/mwan3.pot | 478 ++++++++ .../lean/luci-app-mwan3-alt/po/zh-cn/mwan3.po | 793 +++++++++++++ .../lean/luci-app-mwan3-alt/po/zh-tw/mwan3.po | 793 +++++++++++++ .../root/etc/uci-defaults/60_luci-mwan3 | 21 + package/lean/luci-app-syncdial/Makefile | 17 + .../luasrc/controller/syncdial.lua | 25 + .../luasrc/model/cbi/syncdial.lua | 37 + .../luasrc/view/syncdial/redial_button.htm | 17 + .../lean/luci-app-syncdial/root/bin/genwancfg | 143 +++ .../root/etc/config/syncdial | 7 + .../root/etc/hotplug.d/iface/01-mvifcreate | 16 + .../root/etc/uci-defaults/luci-syncdial | 12 + package/lean/mwan3-alt/Makefile | 68 ++ package/lean/mwan3-alt/files/etc/config/mwan3 | 32 + .../files/etc/hotplug.d/iface/14-mwan3 | 48 + .../files/etc/hotplug.d/iface/15-mwan3 | 95 ++ .../files/etc/hotplug.d/iface/16-mwan3 | 17 + .../files/etc/hotplug.d/iface/16-mwan3-user | 16 + package/lean/mwan3-alt/files/etc/init.d/mwan3 | 20 + package/lean/mwan3-alt/files/etc/mwan3.user | 16 + .../lean/mwan3-alt/files/lib/mwan3/common.sh | 6 + .../lean/mwan3-alt/files/lib/mwan3/mwan3.sh | 1030 +++++++++++++++++ .../mwan3-alt/files/usr/libexec/rpcd/mwan3 | 156 +++ package/lean/mwan3-alt/files/usr/sbin/mwan3 | 239 ++++ .../lean/mwan3-alt/files/usr/sbin/mwan3rtmon | 32 + .../lean/mwan3-alt/files/usr/sbin/mwan3track | 259 +++++ 47 files changed, 7573 insertions(+) create mode 100644 package/lean/luci-app-mwan3-alt/Makefile create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/controller/mwan3.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/globalsconfig.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interface.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interfaceconfig.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/member.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/memberconfig.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/notify.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policy.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policyconfig.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/rule.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/ruleconfig.lua create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/view/admin_status/index/mwan.htm create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/view/mwan/overview_status_interface.htm create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_detail.htm create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_diagnostics.htm create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_interface.htm create mode 100644 package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_troubleshooting.htm create mode 100644 package/lean/luci-app-mwan3-alt/po/de/mwan3.po create mode 100644 package/lean/luci-app-mwan3-alt/po/ja/mwan3.po create mode 100644 package/lean/luci-app-mwan3-alt/po/ru/mwan3.po create mode 100644 package/lean/luci-app-mwan3-alt/po/templates/mwan3.pot create mode 100644 package/lean/luci-app-mwan3-alt/po/zh-cn/mwan3.po create mode 100644 package/lean/luci-app-mwan3-alt/po/zh-tw/mwan3.po create mode 100755 package/lean/luci-app-mwan3-alt/root/etc/uci-defaults/60_luci-mwan3 create mode 100755 package/lean/luci-app-syncdial/Makefile create mode 100644 package/lean/luci-app-syncdial/luasrc/controller/syncdial.lua create mode 100644 package/lean/luci-app-syncdial/luasrc/model/cbi/syncdial.lua create mode 100644 package/lean/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm create mode 100755 package/lean/luci-app-syncdial/root/bin/genwancfg create mode 100644 package/lean/luci-app-syncdial/root/etc/config/syncdial create mode 100644 package/lean/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate create mode 100755 package/lean/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial create mode 100644 package/lean/mwan3-alt/Makefile create mode 100644 package/lean/mwan3-alt/files/etc/config/mwan3 create mode 100644 package/lean/mwan3-alt/files/etc/hotplug.d/iface/14-mwan3 create mode 100644 package/lean/mwan3-alt/files/etc/hotplug.d/iface/15-mwan3 create mode 100644 package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3 create mode 100644 package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3-user create mode 100755 package/lean/mwan3-alt/files/etc/init.d/mwan3 create mode 100644 package/lean/mwan3-alt/files/etc/mwan3.user create mode 100644 package/lean/mwan3-alt/files/lib/mwan3/common.sh create mode 100644 package/lean/mwan3-alt/files/lib/mwan3/mwan3.sh create mode 100755 package/lean/mwan3-alt/files/usr/libexec/rpcd/mwan3 create mode 100755 package/lean/mwan3-alt/files/usr/sbin/mwan3 create mode 100755 package/lean/mwan3-alt/files/usr/sbin/mwan3rtmon create mode 100755 package/lean/mwan3-alt/files/usr/sbin/mwan3track diff --git a/package/lean/luci-app-mwan3-alt/Makefile b/package/lean/luci-app-mwan3-alt/Makefile new file mode 100644 index 000000000..c59011bc0 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2017 Dan Luedtke +# +# 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-alt +libuci-lua +luci-mod-admin-full +luci-app-firewall +luci-lib-nixio +LUCI_PKGARCH:=all +PKG_LICENSE:=GPLv2 + +PKG_MAINTAINER:=Aedan Renner \ + Florian Eckert + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/lean/luci-app-mwan3-alt/luasrc/controller/mwan3.lua b/package/lean/luci-app-mwan3-alt/luasrc/controller/mwan3.lua new file mode 100644 index 000000000..35385912c --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/controller/mwan3.lua @@ -0,0 +1,320 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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 + luci.http.write("Command:\n") + luci.http.write(cmd %{ut.shellquote(device), + ut.shellquote(addr)} .. "\n\n") + luci.http.write("Result:\n") + 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(interface) + 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 i18n = require "luci.i18n" + local network = nw:get_network(interface) + local device = network and network:get_interface() + device = device:name() + + 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(i18n.translatef("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(i18n.translatef("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(i18n.translatef("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(i18n.translatef("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(i18n.translatef("Only one IP rules for interface %s found", interface)) + luci.http.write("\n") + luci.http.write(iif_rule) + else + luci.http.write(i18n.translatef("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(i18n.translatef("Routing table %s for interface %s found", number, interface)) + luci.http.write("\n") + luci.http.write(routeTable) + else + luci.http.write(i18n.translatef("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/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/globalsconfig.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/globalsconfig.lua new file mode 100644 index 000000000..d8f90e1e2 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/globalsconfig.lua @@ -0,0 +1,31 @@ +-- Copyright 2017 Florian Eckert +-- 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 0x")) +mask.datatype = "hex(4)" +mask.default = "0xff00" + +return m diff --git a/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interface.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interface.lua new file mode 100644 index 000000000..162b388d1 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interface.lua @@ -0,0 +1,240 @@ +-- Copyright 2014 Aedan Renner +-- 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("%s
", + translatef("There are currently %d of %d supported interfaces configured", count, iface_max) + ) + else + warnings = string.format("%s
", + 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("%s
", + translatef("WARNING: Interface %s are not found in /etc/config/network", i) + ) + end + + if overview[i]["default_route"] == false then + warnings = warnings .. string.format("%s
", + 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("%s
", + 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("%s
", + 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
" .. + "MWAN requires that all interfaces have a unique metric configured in /etc/config/network
" .. + "Names must match the interface name found in /etc/config/network
" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces
" .. + "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 "—" + 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 "—" + 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 "—" + 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 "—" + 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 "—" + 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 "—" + end +end + +return m5 diff --git a/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interfaceconfig.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interfaceconfig.lua new file mode 100644 index 000000000..ed9d94ac7 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/interfaceconfig.lua @@ -0,0 +1,240 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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(Flag, "enabled", translate("Enabled")) +enabled.default = false + +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 + +max_ttl = mwan_interface:option(Value, "max_ttl", translate("Max TTL")) +max_ttl.default = "60" +max_ttl:depends("track_method", "ping") +max_ttl:value("10") +max_ttl:value("20") +max_ttl:value("30") +max_ttl:value("40") +max_ttl:value("50") +max_ttl:value("60") +max_ttl:value("70") +max_ttl.datatype = "range(1, 255)" + +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 "—" + end +end + +return m5 diff --git a/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/member.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/member.lua new file mode 100644 index 000000000..9b4ab102d --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/member.lua @@ -0,0 +1,44 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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
" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces
" .. + "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 "—" +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/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/memberconfig.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/memberconfig.lua new file mode 100644 index 000000000..27d9a3e85 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/memberconfig.lua @@ -0,0 +1,31 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/notify.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/notify.lua new file mode 100644 index 000000000..4c6e21003 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/notify.lua @@ -0,0 +1,45 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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\".
" .. + "The file is also preserved during sysupgrade.
" .. + "
" .. + "Notes:
" .. + "This file is interpreted as a shell script.
" .. + "The first line of the script must be "#!/bin/sh" without quotes.
" .. + "Lines beginning with # are comments and are not executed.
" .. + "Put your custom mwan3 action here, they will
" .. + "be executed with each netifd hotplug interface event
" .. + "on interfaces for which mwan3 is enabled.
" .. + "
" .. + "There are three main environment variables that are passed to this script.
" .. + "
" .. + "$ACTION
" .. + "* \"ifup\" Is called by netifd and mwan3track
" .. + "* \"ifdown\" Is called by netifd and mwan3track
" .. + "* \"connected\" Is only called by mwan3track if tracking was successful
" .. + "* \"disconnected\" Is only called by mwan3track if tracking has failed
" .. + "$INTERFACE Name of the interface which went up or down (e.g. \"wan\" or \"wwan\")
" .. + "$DEVICE Physical device name which interface went up or down (e.g. \"eth0\" or \"wwan0\")
" .. + "
")) + +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/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policy.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policy.lua new file mode 100644 index 000000000..4543260f6 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policy.lua @@ -0,0 +1,87 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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("%s
", + 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
" .. + "Member interfaces with lower metrics are used first
" .. + "Member interfaces with the same metric will be load-balanced
" .. + "Load-balanced member interfaces distribute more traffic out those with higher weights
" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces
" .. + "Names must be 15 characters or less
" .. + "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 .. "
" + end + return memberList + else + return "—" + 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/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policyconfig.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policyconfig.lua new file mode 100644 index 000000000..d1a063d09 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/policyconfig.lua @@ -0,0 +1,30 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/rule.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/rule.lua new file mode 100644 index 000000000..f0b94bd0b --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/rule.lua @@ -0,0 +1,104 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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("%s
", + 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
" .. + "Rules are based on IP address, port or protocol
" .. + "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
" .. + "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
" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces
" .. + "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 "—" +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 "—" +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 "—" +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 "—" +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 "—" +end + +return m5 diff --git a/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/ruleconfig.lua b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/ruleconfig.lua new file mode 100644 index 000000000..84adfcf91 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/model/cbi/mwan/ruleconfig.lua @@ -0,0 +1,63 @@ +-- Copyright 2014 Aedan Renner +-- Copyright 2018 Florian Eckert +-- 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/package/lean/luci-app-mwan3-alt/luasrc/view/admin_status/index/mwan.htm b/package/lean/luci-app-mwan3-alt/luasrc/view/admin_status/index/mwan.htm new file mode 100644 index 000000000..e4b3c0699 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/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/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/overview_status_interface.htm b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/overview_status_interface.htm new file mode 100644 index 000000000..49d120c1a --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/overview_status_interface.htm @@ -0,0 +1,75 @@ +<%# + Copyright 2014 Aedan Renner + Copyright 2018 Florian Eckert + Licensed to the public under the GNU General Public License v2. +-%> + + + + + +
+ <%:MWAN Interfaces%> +
+ <%:Loading%> + <%:Collecting data...%> +
+
diff --git a/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_detail.htm b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_detail.htm new file mode 100644 index 000000000..12700c4a3 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_detail.htm @@ -0,0 +1,39 @@ +<%# + Copyright 2014 Aedan Renner + Copyright 2018 Florian Eckert + Licensed to the public under the GNU General Public License v2. +-%> + +<%+header%> + + + + + +
+

<%:MWAN Status - Detail%>

+ <%if not require("luci.sys").init.enabled("mwan3") then%> +
<%:INFO: MWAN not running%>
+ <%end%> +
+ + <%:Loading%> + <%:Collecting data...%> + +
+
+ +<%+footer%> diff --git a/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_diagnostics.htm b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_diagnostics.htm new file mode 100644 index 000000000..454adcc1c --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_diagnostics.htm @@ -0,0 +1,90 @@ +<%# + Copyright 2014 Aedan Renner + Copyright 2018 Florian Eckert + Licensed to the public under the GNU General Public License v2. +-%> + +<%+header%> + + + +<% + local uci = require "luci.model.uci" + + local iface = {} + + uci.cursor():foreach("mwan3", "interface", + function (section) + table.insert(iface, section[".name"]) + end + ) +%> + + + +
+
+

<%:MWAN Status - Diagnostics%>

+ <%if not require("luci.sys").init.enabled("mwan3") then%> +
<%:INFO: MWAN not running%>
+ <%end%> +
+
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
+ +
+ +<%+footer%> diff --git a/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_interface.htm b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_interface.htm new file mode 100644 index 000000000..962cde521 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_interface.htm @@ -0,0 +1,20 @@ +<%# + Copyright 2014 Aedan Renner + Copyright 2018 Florian Eckert + Licensed to the public under the GNU General Public License v2. +-%> + +<%+header%> + + + + +
+ <%+mwan/overview_status_interface%> +
+<%+footer%> diff --git a/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_troubleshooting.htm b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_troubleshooting.htm new file mode 100644 index 000000000..a20516bd2 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/luasrc/view/mwan/status_troubleshooting.htm @@ -0,0 +1,39 @@ +<%# + Copyright 2014 Aedan Renner + Copyright 2018 Florian Eckert + Licensed to the public under the GNU General Public License v2. +-%> + +<%+header%> + + + + + +
+

<%:MWAN Status - Troubleshooting%>

+ <%if not require("luci.sys").init.enabled("mwan3") then%> +
<%:INFO: MWAN not running%>
+ <%end%> +
+ + <%:Loading%> + <%:Collecting data...%> + +
+
+ +<%+footer%> diff --git a/package/lean/luci-app-mwan3-alt/po/de/mwan3.po b/package/lean/luci-app-mwan3-alt/po/de/mwan3.po new file mode 100644 index 000000000..641733e5a --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/po/de/mwan3.po @@ -0,0 +1,505 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "%d hour" +msgstr "%d Stunde" + +msgid "%d minute" +msgstr "%d Minute" + +msgid "%d minutes" +msgstr "%d Minuten" + +msgid "%d second" +msgstr "%d Sekunde" + +msgid "%d seconds" +msgstr "%d Sekunden" + +msgid "" +"Acceptable values: 1-100. This many Tracking IP addresses must respond for " +"the link to be deemed up" +msgstr "" +"Gültige Werte: 1-100. Diese Anzahl an Tracking-IP-Adressen müssen antworten, " +"damit die Schnittstelle als aktiv angesehen wird" + +msgid "Acceptable values: 1-1000. Defaults to 1 if not set" +msgstr "Gültige Werte: 1-1000. Standard auf 1, falls nicht gesetzt" + +msgid "Acceptable values: 1-256. Defaults to 1 if not set" +msgstr "" + +msgid "All required IP rules for interface %s found" +msgstr "" + +msgid "Check IP rules" +msgstr "Prüfen der IP-Regeln" + +msgid "Check link quality" +msgstr "" + +msgid "Check routing table" +msgstr "Prüfen der Routing-Tabelle" + +msgid "Collecting data..." +msgstr "Sammle Daten..." + +msgid "Destination address" +msgstr "Zieladresse" + +msgid "Destination port" +msgstr "Zielport" + +msgid "Detail" +msgstr "" + +msgid "Diagnostics" +msgstr "Diagnose" + +msgid "Disabled" +msgstr "Deaktiviert" + +msgid "" +"Downed interface will be deemed up after this many successful ping tests" +msgstr "" +"Eine als offline markierte Schnittstelle wird nach dieser Anzahl " +"erfolgreicher Tracking-Runden als online angesehen" + +msgid "Enabled" +msgstr "Aktiviert" + +msgid "Enter value in hex, starting with 0x" +msgstr "Fehler beim Sammeln von Informationen zur Fehlerbehebung" + +msgid "Execute" +msgstr "" + +msgid "Expect interface state on up event" +msgstr "" + +msgid "Failure interval" +msgstr "Fehler-Intervall" + +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 "" + +msgid "IPv4" +msgstr "" + +msgid "IPv6" +msgstr "" + +msgid "Initial state" +msgstr "" + +msgid "Interface" +msgstr "Schnittstelle" + +msgid "Interface down" +msgstr "Schnittstelle nicht aktiv" + +msgid "Interface up" +msgstr "Schnittstelle aktiv" + +msgid "Interface will be deemed down after this many failed ping tests" +msgstr "" +"Die Schnittstelle wird nach dieser Anzahl an fehlgeschlagenen Tracking-" +"Runden als offline angesehen" + +msgid "Interfaces" +msgstr "Schnittstellen" + +msgid "Internet Protocol" +msgstr "Internet-Protokoll" + +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 "Lade" + +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-Konfiguration, Schnittstelle - %s" + +msgid "MWAN Interfaces" +msgstr "" + +msgid "MWAN Member Configuration - %s" +msgstr "MWAN-Konfiguration, Mitglieder - %s" + +msgid "MWAN Policy Configuration - %s" +msgstr "MWAN-Konfiguration, Richtlinien - %s" + +msgid "MWAN Rule Configuration - %s" +msgstr "MWAN-Konfiguration, Regeln - %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
MWAN " +"requires that all interfaces have a unique metric configured in /etc/config/" +"network
Names must match the interface name found in /etc/config/" +"network
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Interfaces may not share the same name as configured members, policies or " +"rules" +msgstr "" + +msgid "Max TTL" +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 "" +"Kann als einzelner oder mehrfacher Port (z.B. \"22\" oder \"80,443\") oder " +"als Port-Range (z.B. \"1024:2048\") ohne Anführungsstriche eingegeben werden" + +msgid "Member" +msgstr "Mitglied" + +msgid "Member used" +msgstr "Mitglied, in Verwendung" + +msgid "Members" +msgstr "Mitglieder" + +msgid "" +"Members are profiles attaching a metric and weight to an MWAN interface
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Members " +"may not share the same name as configured interfaces, policies or rules" +msgstr "" +"Mitglieder sind Profile, die eine Metrik und Gewichtung and eine MWAN-" +"Schnittstelle anhängen
Namen dürfen folgende Zeichen enthalten: A-Z, a-" +"z, 0-9, _ und keine Leerzeichen
Mitglieder dürfen nicht denselben Namen " +"mit konfigurierten Schnittstellen, Richtlinien oder Regeln teilen" + +msgid "Members assigned" +msgstr "Mitglieder, zugewiesen" + +msgid "Metric" +msgstr "Metrik" + +msgid "Min packet latency [ms]" +msgstr "" + +msgid "Min packet loss [%]" +msgstr "" + +msgid "Missing both IP rules for interface %s" +msgstr "" + +msgid "" +"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/" +"youtube.com/youtube\")" +msgstr "" +"Name der IPset-Regel. Benötigt eine IPset-Regel in /etc/dnsmasq.conf (z.B. " +"\"ipset=/youtube.com/youtube\")" + +msgid "No" +msgstr "Nein" + +msgid "No MWAN interfaces found" +msgstr "Keine MWAN-Schnittstellen gefunden" + +msgid "No gateway for interface %s found." +msgstr "" + +msgid "No tracking Hosts for interface %s defined." +msgstr "" + +msgid "Notification" +msgstr "" + +msgid "Offline" +msgstr "" + +msgid "Online" +msgstr "" + +msgid "Only one IP rules for interface %s found" +msgstr "" + +msgid "Ping count" +msgstr "Ping-Zähler" + +msgid "Ping default gateway" +msgstr "Ping-Standard-Gateway" + +msgid "Ping interval" +msgstr "Ping-Intervall" + +msgid "Ping interval during failure detection" +msgstr "Ping-Intervall während Fehlererkennung" + +msgid "Ping interval during failure recovering" +msgstr "Ping-Intervall während der Wiederherstellung" + +msgid "Ping size" +msgstr "Ping-Größe" + +msgid "Ping timeout" +msgstr "Ping-Timeout" + +msgid "Ping tracking IP" +msgstr "Ping-Tracking-IP" + +msgid "Policies" +msgstr "Richtlinien" + +msgid "" +"Policies are profiles grouping one or more members controlling how MWAN " +"distributes traffic
Member interfaces with lower metrics are used " +"first
Member interfaces with the same metric will be load-balanced
Load-balanced member interfaces distribute more traffic out those with " +"higher weights
Names may contain characters A-Z, a-z, 0-9, _ and no " +"spaces
Names must be 15 characters or less
Policies may not share " +"the same name as configured interfaces, members or rules" +msgstr "" + +msgid "Policy" +msgstr "Richtlinie" + +msgid "Policy assigned" +msgstr "Richtlinie, zugewiesen" + +msgid "Protocol" +msgstr "Protokoll" + +msgid "Recovery interval" +msgstr "Wiederherstellungs-Intervall" + +msgid "Routing table %s for interface %s found" +msgstr "" + +msgid "Routing table %s for interface %s not found" +msgstr "" + +msgid "Rule" +msgstr "Regel" + +msgid "Rules" +msgstr "Regeln" + +msgid "" +"Rules specify which traffic will use a particular MWAN policy
Rules are " +"based on IP address, port or protocol
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
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
Names may contain characters A-Z, a-" +"z, 0-9, _ and no spaces
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 "" +"Sekunden. Gültige Werte: 1-1000000. Standard bei 600 falls nicht gesetzt" + +msgid "Source address" +msgstr "Quelladresse" + +msgid "Source port" +msgstr "Quellport" + +msgid "Sticky" +msgstr "" + +msgid "Sticky timeout" +msgstr "Sticky-Timeout" + +msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes" +msgstr "" +"Unterstützt CIDR-Schreibweise (z.B. \"192.168.100.0/24\") ohne " +"Anführungsstriche" + +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 "" +"Zeigt die Metrik an, die dieser Schnittstelle in /etc/config/network " +"zugeordnet ist" + +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 "" +"Dieser Hostname oder die IP-Adresse wird gepingt, um festzustellen, ob der " +"Link aktiv oder inaktiv ist. Leer lassen, um die Schnittstelle als dauerhaft " +"online anzusehen" + +msgid "" +"This section allows you to modify the content of \"/etc/mwan3.user\".
The file is also preserved during sysupgrade.

Notes:
This " +"file is interpreted as a shell script.
The first line of the script " +"must be "#!/bin/sh" without quotes.
Lines beginning with # are " +"comments and are not executed.
Put your custom mwan3 action here, they " +"will
be executed with each netifd hotplug interface event
on " +"interfaces for which mwan3 is enabled.

There are three main " +"environment variables that are passed to this script.

$ACTION " +"
* \"ifup\" Is called by netifd and mwan3track
* \"ifdown\" Is " +"called by netifd and mwan3track
* \"connected\" Is only called by " +"mwan3track if tracking was successful
* \"disconnected\" Is only " +"called by mwan3track if tracking has failed
$INTERFACE Name of the " +"interface which went up or down (e.g. \"wan\" or \"wwan\")
$DEVICE " +"Physical device name which interface went up or down (e.g. \"eth0\" or " +"\"wwan0\")

" +msgstr "" + +msgid "Tracking hostname or IP address" +msgstr "Tracking des Hostnamen oder der IP-Addresse" + +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 "" +"Traffic von der gleichen Quell-IP-Adresse, die zuvor dieser Regel innerhalb " +"der festgelegten Timeout-Periode entspricht, wird die gleiche WAN-" +"Schnittstelle verwenden" + +msgid "Troubleshooting" +msgstr "Fehlerbehebung" + +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 "Gewichtung" + +msgid "" +"When all policy members are offline use this behavior for matched traffic" +msgstr "" +"Sobald alle Mitglieder der Richtlinie offline sind, wird dieses Verhalten " +"für passenden Traffic verwendet" + +msgid "Yes" +msgstr "Ja" + +msgid "always" +msgstr "immer" + +msgid "blackhole (drop)" +msgstr "" + +msgid "default (use main routing table)" +msgstr "default (Haupt-Routing-Tabelle wird benutzt)" + +msgid "ifdown" +msgstr "" + +msgid "ifup" +msgstr "" + +msgid "never" +msgstr "nie" + +msgid "unreachable (reject)" +msgstr "unerreichbar (rejectet)" diff --git a/package/lean/luci-app-mwan3-alt/po/ja/mwan3.po b/package/lean/luci-app-mwan3-alt/po/ja/mwan3.po new file mode 100644 index 000000000..40c71b00a --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/po/ja/mwan3.po @@ -0,0 +1,563 @@ +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 \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 "All required IP rules for interface %s found" +msgstr "" + +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 0x" +msgstr "0x で始まる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
MWAN " +"requires that all interfaces have a unique metric configured in /etc/config/" +"network
Names must match the interface name found in /etc/config/" +"network
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Interfaces may not share the same name as configured members, policies or " +"rules" +msgstr "" +"MWAN は、252個までの物理または論理、あるいは両方のインターフェースをサポート" +"します。
MWAN は、全てのインターフェースが /etc/config/network で設定さ" +"れるユニークなメトリックを持つことを必要とします。
下記 \"インターフェー" +"ス\" の名前は、 /etc/config/network に存在するインターフェース名と同じでなけ" +"ればなりません。
名前は A-Z, a-z, 0-9, _ を含むことができますが、スペー" +"スは使用できません。
インターフェースには、設定済みのメンバーやポリ" +"シー、ルールと同じ名前を使用することはできません。" + +msgid "Max TTL" +msgstr "" + +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
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Members " +"may not share the same name as configured interfaces, policies or rules" +msgstr "" +"メンバーは、MWAN インターフェースのメトリックおよびウエイトを関連付けたプロ" +"ファイルです。
名前は A-Z, a-z, 0-9, _ を含むことができますが、スペース" +"は使用できません。
メンバーには、設定済みのインターフェースやポリシー、" +"ルールと同じ名前を使用することはできません。" + +msgid "Members assigned" +msgstr "アサイン済みメンバー" + +msgid "Metric" +msgstr "メトリック" + +msgid "Min packet latency [ms]" +msgstr "最小パケットレイテンシ [ms]" + +msgid "Min packet loss [%]" +msgstr "最小パケットロス [%]" + +msgid "Missing both IP rules for interface %s" +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 "No gateway for interface %s found." +msgstr "" + +msgid "No tracking Hosts for interface %s defined." +msgstr "" + +msgid "Notification" +msgstr "通知" + +msgid "Offline" +msgstr "オフライン" + +msgid "Online" +msgstr "オンライン" + +msgid "Only one IP rules for interface %s found" +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
Member interfaces with lower metrics are used " +"first
Member interfaces with the same metric will be load-balanced
Load-balanced member interfaces distribute more traffic out those with " +"higher weights
Names may contain characters A-Z, a-z, 0-9, _ and no " +"spaces
Names must be 15 characters or less
Policies may not share " +"the same name as configured interfaces, members or rules" +msgstr "" +"ポリシーは、MWANがどのようにトラフィックの分配を行うかを制御する、1つ以上のメ" +"ンバーをグループ化するプロファイルです。
最小のメトリックを持つメンバー " +"インターフェースが最初に使用されます。同じメトリックを持つ複数のインター" +"フェースでは、負荷分散を行います。
負荷分散に設定されたメンバー インター" +"フェースでは、ウェイトの値が大きい方により多くのトラフィックを分配します。" +"
名前は A-Z, a-z, 0-9, _ を含むことができますが、スペースは使用できませ" +"ん。また、15文字以内でなければなりません。
ポリシーでは、設定済みのイン" +"ターフェースやメンバー、ルールと同じ名前を使用することはできません。" + +msgid "Policy" +msgstr "ポリシー" + +msgid "Policy assigned" +msgstr "アサイン済みポリシー" + +msgid "Protocol" +msgstr "プロトコル" + +msgid "Recovery interval" +msgstr "障害復旧 インターバル" + +msgid "Routing table %s for interface %s found" +msgstr "" + +msgid "Routing table %s for interface %s not found" +msgstr "" + +msgid "Rule" +msgstr "ルール" + +msgid "Rules" +msgstr "ルール" + +msgid "" +"Rules specify which traffic will use a particular MWAN policy
Rules are " +"based on IP address, port or protocol
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
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
Names may contain characters A-Z, a-" +"z, 0-9, _ and no spaces
Rules may not share the same name as configured " +"interfaces, members or policies" +msgstr "" +"ルールは、どのトラフィックが特定の MWAN ポリシーを使用するかを指定します
ルールは IP アドレスやポート、プロトコルに基づいています
ルールは上から" +"下へマッチングが行われます
合致したルールより下のルールは無視されます" +"
いずれのルールにもマッチしないトラフィックは、メインのルーティングテー" +"ブルを使用してルーティングされます
既知(デフォルト以外)のネットワーク" +"へのトラフィックは、メインのルーティングテーブルによって制御されます
ト" +"ラフィックがルールに合致しても、全 WAN インターフェースが down の場合は " +"blackhole 状態となります
名前は A-Z, a-z, 0-9, _ を含むことができます" +"が、スペースは使用できません
ルールは、設定済みのインターフェースやメン" +"バー、ポリシーと同じ名前を使用することはできません。" + +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\".
The file is also preserved during sysupgrade.

Notes:
This " +"file is interpreted as a shell script.
The first line of the script " +"must be "#!/bin/sh" without quotes.
Lines beginning with # are " +"comments and are not executed.
Put your custom mwan3 action here, they " +"will
be executed with each netifd hotplug interface event
on " +"interfaces for which mwan3 is enabled.

There are three main " +"environment variables that are passed to this script.

$ACTION " +"
* \"ifup\" Is called by netifd and mwan3track
* \"ifdown\" Is " +"called by netifd and mwan3track
* \"connected\" Is only called by " +"mwan3track if tracking was successful
* \"disconnected\" Is only " +"called by mwan3track if tracking has failed
$INTERFACE Name of the " +"interface which went up or down (e.g. \"wan\" or \"wwan\")
$DEVICE " +"Physical device name which interface went up or down (e.g. \"eth0\" or " +"\"wwan0\")

" +msgstr "" +"このセクションでは、 \"/etc/mwan3.user\" の内容を変更することができます。" +"
このファイルも sysupgrade の際に保持されます。

注意:
" +"このファイルはシェルスクリプトとして解釈されます。
最初の行は "#!/" +"bin/sh" である必要があります(クォーテーション不要)。
# で始まる行" +"はコメントであり、実行されません。
mwan3 のカスタム動作をここに入力して" +"ください。
これらは、mwan3 で有効なインターフェースの
netifd " +"hotplug インターフェース イベント毎に実行されます。

このスクリプト" +"に受け渡される主に3つの環境変数が利用できます。

$ACTION
* " +"\"ifup\" は netifd と mwan3track により呼び出されます
* \"ifdown\" は " +"netifd と mwan3track により呼び出されます
* \"connected\" はトラッキング" +"が成功した際に mwan3track にのみにより呼び出されます
* \"disconnected\" " +"は トラッキングが失敗した際に mwan3track のみにより呼び出されます
" +"$INTERFACE up または down したインターフェース名(例: \"wan\" や \"wwan\")" +"
$DEVICE up または down したインターフェースの物理デバイス名(例: " +"\"eth0\" や \"wwan0\")

" + +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/package/lean/luci-app-mwan3-alt/po/ru/mwan3.po b/package/lean/luci-app-mwan3-alt/po/ru/mwan3.po new file mode 100644 index 000000000..884848da4 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/po/ru/mwan3.po @@ -0,0 +1,592 @@ +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 \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-адресов.
Сколько раз они должны ответить, чтобы соединение было признано активным." + +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 "All required IP rules for interface %s found" +msgstr "" + +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 0x" +msgstr "Введите значение в шестнадцатеричной форме, начиная с 0x." + +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
MWAN " +"requires that all interfaces have a unique metric configured in /etc/config/" +"network
Names must match the interface name found in /etc/config/" +"network
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Interfaces may not share the same name as configured members, policies or " +"rules" +msgstr "" +"MWAN поддерживает до 252 физических и / или логических интерфейсов.
MWAN требует, чтобы все интерфейсы имели уникальную метрику, настроенную в " +"config файле /etc/config/network.
Имена должны соответствовать имени " +"интерфейса, найденному в /etc/config/network.
Имена могут содержать " +"символы A-Z, a-z, 0-9, _ и пробелы.
Интерфейсы не могут иметь " +"одинаковые имена с настроенными узлами, политиками или правилами." + +msgid "Max TTL" +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 "" +"Может быть введено как один или несколько портов (например, '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
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Members " +"may not share the same name as configured interfaces, policies or rules" +msgstr "" +"Узлы имеют профили, содержащие метрику и вес к интерфейсу MWAN.
Имена " +"могут содержать символы A-Z, a-z, 0-9, _ и пробелы.
Узлы не могут иметь " +"одинаковые имена с настроенными интерфейсами, политиками или правилами." + +msgid "Members assigned" +msgstr "Назначенные узлы" + +msgid "Metric" +msgstr "Метрика" + +msgid "Min packet latency [ms]" +msgstr "" + +msgid "Min packet loss [%]" +msgstr "" + +msgid "Missing both IP rules for interface %s" +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 "No gateway for interface %s found." +msgstr "" + +msgid "No tracking Hosts for interface %s defined." +msgstr "" + +msgid "Notification" +msgstr "Уведомления" + +msgid "Offline" +msgstr "Отключен" + +msgid "Online" +msgstr "Онлайн" + +msgid "Only one IP rules for interface %s found" +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
Member interfaces with lower metrics are used " +"first
Member interfaces with the same metric will be load-balanced
Load-balanced member interfaces distribute more traffic out those with " +"higher weights
Names may contain characters A-Z, a-z, 0-9, _ and no " +"spaces
Names must be 15 characters or less
Policies may not share " +"the same name as configured interfaces, members or rules" +msgstr "" +"Политики это профили, объединяющие один или несколько узлов, контролирующих, " +"как MWAN распределяет трафик.
Сначала используются интерфейсы-узлы с " +"более низкими метриками. Интерфейсы с одинаковым метрическим балансом " +"нагрузки.
Интерфейсы элементов с балансировкой нагрузки распределяют " +"больше трафика с более высокими значениями.
Имена могут содержать " +"символы A-Z, a-z, 0-9, _ и пробелы. Имена должны быть не более 15 символов." +"
Политики не могут иметь одинаковые имена с настроенными интерфейсами, " +"узлами или правилами." + +msgid "Policy" +msgstr "Политика" + +msgid "Policy assigned" +msgstr "Назначенная политика" + +msgid "Protocol" +msgstr "Протокол" + +msgid "Recovery interval" +msgstr "Интервал восстановления" + +msgid "Routing table %s for interface %s found" +msgstr "" + +msgid "Routing table %s for interface %s not found" +msgstr "" + +msgid "Rule" +msgstr "Правило" + +msgid "Rules" +msgstr "Правила" + +msgid "" +"Rules specify which traffic will use a particular MWAN policy
Rules are " +"based on IP address, port or protocol
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
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
Names may contain characters A-Z, a-" +"z, 0-9, _ and no spaces
Rules may not share the same name as configured " +"interfaces, members or policies" +msgstr "" +"Правила определяют, какой трафик будет использовать конкретную политику MWAN." +"
Правила основываются на IP-адресе, порту или протоколе.
Список " +"правил исполняется сверху вниз.
Правила, расположенные ниже правила " +"сопоставления, игнорируются.
Трафик, не соответствующий никакому " +"правилу, маршрутизируется с помощью основной таблицы маршрутизации.
Трафик, предназначенный для известных (не по умолчанию) сетей, " +"обрабатывается основной таблицей маршрутизации.
Трафик соответствует " +"правилам, но все интерфейсы WAN для этой политики будут заблокированы.
Имена могут содержать символы A-Z, a-z, 0-9, _ , пробелы запрещены.
Правила не могут иметь одинаковые имена с настроенными интерфейсами, узлами " +"или политиками." + +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-адрес для пинг-запроса, чтобы определить активно ли " +"соединение или нет.
Оставьте пустым, чтобы предположить, что интерфейс " +"всегда находится в сети." + +msgid "" +"This section allows you to modify the content of \"/etc/mwan3.user\".
The file is also preserved during sysupgrade.

Notes:
This " +"file is interpreted as a shell script.
The first line of the script " +"must be "#!/bin/sh" without quotes.
Lines beginning with # are " +"comments and are not executed.
Put your custom mwan3 action here, they " +"will
be executed with each netifd hotplug interface event
on " +"interfaces for which mwan3 is enabled.

There are three main " +"environment variables that are passed to this script.

$ACTION " +"
* \"ifup\" Is called by netifd and mwan3track
* \"ifdown\" Is " +"called by netifd and mwan3track
* \"connected\" Is only called by " +"mwan3track if tracking was successful
* \"disconnected\" Is only " +"called by mwan3track if tracking has failed
$INTERFACE Name of the " +"interface which went up or down (e.g. \"wan\" or \"wwan\")
$DEVICE " +"Physical device name which interface went up or down (e.g. \"eth0\" or " +"\"wwan0\")

" +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\".
The file is also preserved during sysupgrade.

Notes:
This file is interpreted as a shell script.
The first line of the " +#~ "script must be "#!/bin/sh" without quotes.
Lines beginning " +#~ "with # are comments and are not executed.
Put your custom mwan3 " +#~ "action here, they will
be executed with each netifd hotplug " +#~ "interface event
on interfaces for which mwan3 is enabled.

There are three main environment variables that are passed to this " +#~ "script.

$ACTION Either \"ifup\" or \"ifdown\"
$INTERFACE " +#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan" +#~ "\")
$DEVICE Physical device name which interface went up or down (e." +#~ "g. \"eth0\" or \"wwan0\")

" +#~ msgstr "" +#~ "Страница позволяет изменять содержимое файла mwan3.user (/etc/mwan3.user)." +#~ "
Файл также сохраняется во время перепрошивки sysupgrade-совместимым " +#~ "образом.

Примечание:
Этот файл интерпретируется как shell " +#~ "скрипт.
Первая строка скрипта должна быть "#!/bin/sh" без " +#~ "кавычек.
Строки начинающиеся с #, являются комментариями и не " +#~ "исполняются.
Поместите свои пользовательские действия mwan3 здесь, " +#~ "они будут
выполняться с каждым событием netifd hotplug " +#~ "интерфейса
на интерфейсах, для которых включен mwan3.

В " +#~ "этот сценарий передаются три основные переменные среды.

" +#~ "$ACTION либо \"ifup\" или \"ifdown\"
$INTERFACE - имя интерфейса, " +#~ "который включили или отключили (например, 'wan' или 'wwan')
$DEVICE " +#~ "- имя физического устройства, чей интерфейс включили или отключили " +#~ "(например, 'eth0' или 'wwan0')

." diff --git a/package/lean/luci-app-mwan3-alt/po/templates/mwan3.pot b/package/lean/luci-app-mwan3-alt/po/templates/mwan3.pot new file mode 100644 index 000000000..8f43b3dd1 --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/po/templates/mwan3.pot @@ -0,0 +1,478 @@ +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 "All required IP rules for interface %s found" +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 0x" +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
MWAN " +"requires that all interfaces have a unique metric configured in /etc/config/" +"network
Names must match the interface name found in /etc/config/" +"network
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Interfaces may not share the same name as configured members, policies or " +"rules" +msgstr "" + +msgid "Max TTL" +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
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
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 "Missing both IP rules for interface %s" +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 "No gateway for interface %s found." +msgstr "" + +msgid "No tracking Hosts for interface %s defined." +msgstr "" + +msgid "Notification" +msgstr "" + +msgid "Offline" +msgstr "" + +msgid "Online" +msgstr "" + +msgid "Only one IP rules for interface %s found" +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
Member interfaces with lower metrics are used " +"first
Member interfaces with the same metric will be load-balanced
Load-balanced member interfaces distribute more traffic out those with " +"higher weights
Names may contain characters A-Z, a-z, 0-9, _ and no " +"spaces
Names must be 15 characters or less
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 "Routing table %s for interface %s found" +msgstr "" + +msgid "Routing table %s for interface %s not found" +msgstr "" + +msgid "Rule" +msgstr "" + +msgid "Rules" +msgstr "" + +msgid "" +"Rules specify which traffic will use a particular MWAN policy
Rules are " +"based on IP address, port or protocol
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
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
Names may contain characters A-Z, a-" +"z, 0-9, _ and no spaces
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\".
The file is also preserved during sysupgrade.

Notes:
This " +"file is interpreted as a shell script.
The first line of the script " +"must be "#!/bin/sh" without quotes.
Lines beginning with # are " +"comments and are not executed.
Put your custom mwan3 action here, they " +"will
be executed with each netifd hotplug interface event
on " +"interfaces for which mwan3 is enabled.

There are three main " +"environment variables that are passed to this script.

$ACTION " +"
* \"ifup\" Is called by netifd and mwan3track
* \"ifdown\" Is " +"called by netifd and mwan3track
* \"connected\" Is only called by " +"mwan3track if tracking was successful
* \"disconnected\" Is only " +"called by mwan3track if tracking has failed
$INTERFACE Name of the " +"interface which went up or down (e.g. \"wan\" or \"wwan\")
$DEVICE " +"Physical device name which interface went up or down (e.g. \"eth0\" or " +"\"wwan0\")

" +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/package/lean/luci-app-mwan3-alt/po/zh-cn/mwan3.po b/package/lean/luci-app-mwan3-alt/po/zh-cn/mwan3.po new file mode 100644 index 000000000..91475a61e --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/po/zh-cn/mwan3.po @@ -0,0 +1,793 @@ +# +# Yangfl , 2017, 2018. +# +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Last-Translator: Yangfl \n" +"Language-Team: \n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"PO-Revision-Date: 2018-10-01 10:10+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 "All required IP rules for interface %s found" +msgstr "找到接口 %s 的所有必需 IP 规则" + +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 0x" +msgstr "输入十六进制值,以 0x 开头" + +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 状态 - 详细" + +msgid "MWAN Status - Diagnostics" +msgstr "MWAN 状态 - 诊断" + +msgid "MWAN Status - Troubleshooting" +msgstr "MWAN 状态 - 故障排除" + +msgid "" +"MWAN supports up to 252 physical and/or logical interfaces
MWAN " +"requires that all interfaces have a unique metric configured in /etc/config/" +"network
Names must match the interface name found in /etc/config/" +"network
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Interfaces may not share the same name as configured members, policies or " +"rules" +msgstr "" +"MWAN 支持最多 252 个物理或逻辑接口。
MWAN 要求所有接口必须在 /etc/" +"config/network 中设定唯一的网关跃点。
名称必须与 /etc/config/network 中" +"的接口名称匹配。
名称允许包括 A-Z、a-z、0-9、_ 但是不能有空格。
接" +"口不应该与成员、策略、规则中的任意一个设置项使用相同的名称" + +msgid "Max TTL" +msgstr "" + +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
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Members " +"may not share the same name as configured interfaces, policies or rules" +msgstr "" +"“成员”用来设置每一个 MWAN 接口的跃点数(即接口优先级)和所占比重。
名称" +"允许包括 A-Z、 a-、0-9、_ 但是不能有空格。
成员不应该与接口、策略、规则" +"中的任意一个设置项使用相同的名称" + +msgid "Members assigned" +msgstr "分配的成员" + +msgid "Metric" +msgstr "跃点数" + +msgid "Min packet latency [ms]" +msgstr "最小数据包延迟 [ms]" + +msgid "Min packet loss [%]" +msgstr "最小数据包丢失率 [%]" + +msgid "Missing both IP rules for interface %s" +msgstr "缺少接口 %s 的两个 IP 规则" + +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 "No gateway for interface %s found." +msgstr "没有找到接口 %s 的网关。" + +msgid "No tracking Hosts for interface %s defined." +msgstr "未定义接口 %s 的跟踪主机。" + +msgid "Notification" +msgstr "通知" + +msgid "Offline" +msgstr "离线" + +msgid "Online" +msgstr "在线" + +msgid "Only one IP rules for interface %s found" +msgstr "只找到接口 %s 的一个 IP 规则" + +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
Member interfaces with lower metrics are used " +"first
Member interfaces with the same metric will be load-balanced
Load-balanced member interfaces distribute more traffic out those with " +"higher weights
Names may contain characters A-Z, a-z, 0-9, _ and no " +"spaces
Names must be 15 characters or less
Policies may not share " +"the same name as configured interfaces, members or rules" +msgstr "" +"“策略”把成员进行分组,告诉 MWAN 如何分配“规则”中使用这一策略的流量
拥有" +"较低跃点数的成员将会被优先使用。拥有相同跃点数的成员把流量进行负载均衡。
进行负载均衡的成员之间拥有较高比重的成员将会被分配到更多流量。
名称允许" +"包括 A-Z、a-z、0-9、_ 但是不能有空格。名称应该在 15 个字符以内
策略不应" +"该与接口、成员、规则中的任意一个设置项使用相同的名称" + +msgid "Policy" +msgstr "策略" + +msgid "Policy assigned" +msgstr "分配的策略" + +msgid "Protocol" +msgstr "通信协议" + +msgid "Recovery interval" +msgstr "故障恢复间隔" + +msgid "Routing table %s for interface %s found" +msgstr "找到路由表 %s,为接口 %s" + +msgid "Routing table %s for interface %s not found" +msgstr "没有找到路由表 %s,为接口 %s" + +msgid "Rule" +msgstr "规则" + +msgid "Rules" +msgstr "规则" + +msgid "" +"Rules specify which traffic will use a particular MWAN policy
Rules are " +"based on IP address, port or protocol
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
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
Names may contain characters A-Z, a-" +"z, 0-9, _ and no spaces
Rules may not share the same name as configured " +"interfaces, members or policies" +msgstr "" +"规则指定哪些流量将使用特定的 MWAN 策略
规则基于 IP 地址,端口或协议
规则从上到下匹配
匹配规则以下的规则被忽略
不符合任何规则的流量将使" +"用主路由表进行路由
目的地为已知(非默认)网络的流量由主路由表处理
" +"流量符合规则,但该策略的所有 WAN 接口关闭后都会被失效
名称可包含字符 A-" +"Z,a-z,0-9,_ 和空格
规则不能与配置的接口、成员或策略共享相同的名称" + +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\".
The file is also preserved during sysupgrade.

Notes:
This " +"file is interpreted as a shell script.
The first line of the script " +"must be "#!/bin/sh" without quotes.
Lines beginning with # are " +"comments and are not executed.
Put your custom mwan3 action here, they " +"will
be executed with each netifd hotplug interface event
on " +"interfaces for which mwan3 is enabled.

There are three main " +"environment variables that are passed to this script.

$ACTION " +"
* \"ifup\" Is called by netifd and mwan3track
* \"ifdown\" Is " +"called by netifd and mwan3track
* \"connected\" Is only called by " +"mwan3track if tracking was successful
* \"disconnected\" Is only " +"called by mwan3track if tracking has failed
$INTERFACE Name of the " +"interface which went up or down (e.g. \"wan\" or \"wwan\")
$DEVICE " +"Physical device name which interface went up or down (e.g. \"eth0\" or " +"\"wwan0\")

" +msgstr "" +"这里允许您修改“/etc/mwan3.user”的内容。
该文件在 sysupgrade 期间也会保" +"留。

注意:
该文件会作为 shell 脚本解释。
脚本的第一行必" +"须是 "#!/bin/sh",不带引号。
以 # 开头的行是注释,不会执行。" +"
将您的自定义 mwan3 动作放在这里,他们将
在启用 mwan3 的接口上
在 netifd hotplug 接口事件时执行。

有三个主要的环境变量传递给这个" +"脚本。

$ACTION “ifup”或“ifdown”
$INTERFACE 启动或停止的接口名" +"(例如“wan”或“wwan”)
$DEVICE 启动或停止接口的物理设备名(例" +"如“eth0”或“wwan0”)

" + +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\".
The file is also preserved during sysupgrade.

Notes:
This file is interpreted as a shell script.
The first line of the " +#~ "script must be "#!/bin/sh" without quotes.
Lines beginning " +#~ "with # are comments and are not executed.
Put your custom mwan3 " +#~ "action here, they will
be executed with each netifd hotplug " +#~ "interface event
on interfaces for which mwan3 is enabled.

There are three main environment variables that are passed to this " +#~ "script.

$ACTION Either \"ifup\" or \"ifdown\"
$INTERFACE " +#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan" +#~ "\")
$DEVICE Physical device name which interface went up or down (e." +#~ "g. \"eth0\" or \"wwan0\")

" +#~ msgstr "" +#~ "这里允许您修改“/etc/mwan3.user”的内容。
该文件在 sysupgrade 期间也会" +#~ "保留。

注意:
该文件会作为 shell 脚本解释。
脚本的第" +#~ "一行必须是"#!/bin/sh",不带引号。
以#开头的行是注释,不会执" +#~ "行。
将您的自定义 mwan3 动作放在这里,他们将
在启用 mwan3 的接口" +#~ "上
在 netifd hotplug 接口事件时执行。

有三个主要的环境变量" +#~ "传递给这个脚本。

$ACTION “ifup”或“ifdown”
$INTERFACE 启动" +#~ "或停止的接口名(例如“wan”或“wwan”)
$DEVICE 启动或停止接口的物理设备" +#~ "名(例如“eth0”或“wwan0”)

" + +#~ 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
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
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
Names may contain characters A-Z, a-z, 0-9, _ and " +#~ "no spaces
Rules may not share the same name as configured " +#~ "interfaces, members or policies" +#~ msgstr "" +#~ "“规则”基于 IP 地址、协议、端口把流量划分到指定的“策略”中。
规则按照从" +#~ "上到下的顺序进行匹配。除了第一条能够匹配一次通信的规则以外,其它规则将被忽" +#~ "略。不匹配任何规则的通信将会由系统默认路由表进行。
来自已知的网络的转" +#~ "发流量由系统默认路由表接手,然后 MWAN 从中匹配出相应的流量并转移到 MWAN 自" +#~ "己的路由表。但是所有被划分到一个无法使用的策略的流量将会无法正常进行路由。" +#~ "
名称允许包括A-Z、a-z、0-9、_ 但是不能有空格。
规则不应该与接" +#~ "口、成员、策略中的任意一个设置项使用相同的名称" + +#~ 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
This is useful for running system commands and/or scripts " +#~ "based on interface ifup or ifdown hotplug events

Notes:
The first line of the script must be "#!/bin/sh" without " +#~ "quotes
Lines beginning with # are comments and are not executed

Available variables:
$ACTION is the hotplug event (ifup, " +#~ "ifdown)
$INTERFACE is the interface name (wan1, wan2, etc.)
" +#~ "$DEVICE is the device name attached to the interface (eth0.1, eth1, etc.)" +#~ msgstr "" +#~ "这里允许您修改 /etc/hotplug.d/iface/16-mwancustom 的内容
这可以在接" +#~ "口 ifup 或 ifdown Hotplug 事件时运行系统命令或脚本

注意:
" +#~ "脚本的第一行必须是 "#!/bin/sh" 不含引号
以#开头的行是注释," +#~ "不会执行

可用变量:
$ACTION 是 Hotplug 事件(ifup, ifdown)" +#~ "
$INTERFACE 是接口名称(wan1、wan2 等)
$DEVICE 是连接到接口的设" +#~ "备名称 (eth0.1、eth1 等)" diff --git a/package/lean/luci-app-mwan3-alt/po/zh-tw/mwan3.po b/package/lean/luci-app-mwan3-alt/po/zh-tw/mwan3.po new file mode 100644 index 000000000..3aaf030cf --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/po/zh-tw/mwan3.po @@ -0,0 +1,793 @@ +# +# Yangfl , 2017, 2018. +# +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Last-Translator: Yangfl \n" +"Language-Team: \n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"PO-Revision-Date: 2018-10-01 10:10+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 "All required IP rules for interface %s found" +msgstr "找到介面 %s 的所有必需 IP 規則" + +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 0x" +msgstr "輸入十六進位制值,以 0x 開頭" + +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 狀態 - 詳細" + +msgid "MWAN Status - Diagnostics" +msgstr "MWAN 狀態 - 診斷" + +msgid "MWAN Status - Troubleshooting" +msgstr "MWAN 狀態 - 故障排除" + +msgid "" +"MWAN supports up to 252 physical and/or logical interfaces
MWAN " +"requires that all interfaces have a unique metric configured in /etc/config/" +"network
Names must match the interface name found in /etc/config/" +"network
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Interfaces may not share the same name as configured members, policies or " +"rules" +msgstr "" +"MWAN 支援最多 252 個物理或邏輯介面。
MWAN 要求所有介面必須在 /etc/" +"config/network 中設定唯一的閘道器躍點。
名稱必須與 /etc/config/network " +"中的介面名稱匹配。
名稱允許包括 A-Z、a-z、0-9、_ 但是不能有空格。
" +"接口不應該與成員、策略、規則中的任意一個設定項使用相同的名稱" + +msgid "Max TTL" +msgstr "" + +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
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Members " +"may not share the same name as configured interfaces, policies or rules" +msgstr "" +"“成員”用來設定每一個 MWAN 介面的躍點數(即介面優先順序)和所佔比重。
名" +"稱允許包括 A-Z、 a-、0-9、_ 但是不能有空格。
成員不應該與介面、策略、規" +"則中的任意一個設定項使用相同的名稱" + +msgid "Members assigned" +msgstr "分配的成員" + +msgid "Metric" +msgstr "躍點數" + +msgid "Min packet latency [ms]" +msgstr "最小資料包延遲 [ms]" + +msgid "Min packet loss [%]" +msgstr "最小資料包丟失率 [%]" + +msgid "Missing both IP rules for interface %s" +msgstr "缺少介面 %s 的兩個 IP 規則" + +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 "No gateway for interface %s found." +msgstr "沒有找到介面 %s 的閘道器。" + +msgid "No tracking Hosts for interface %s defined." +msgstr "未定義介面 %s 的跟蹤主機。" + +msgid "Notification" +msgstr "通知" + +msgid "Offline" +msgstr "離線" + +msgid "Online" +msgstr "在線" + +msgid "Only one IP rules for interface %s found" +msgstr "只找到介面 %s 的一個 IP 規則" + +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
Member interfaces with lower metrics are used " +"first
Member interfaces with the same metric will be load-balanced
Load-balanced member interfaces distribute more traffic out those with " +"higher weights
Names may contain characters A-Z, a-z, 0-9, _ and no " +"spaces
Names must be 15 characters or less
Policies may not share " +"the same name as configured interfaces, members or rules" +msgstr "" +"“策略”把成員進行分組,告訴 MWAN 如何分配“規則”中使用這一策略的流量
擁有" +"較低躍點數的成員將會被優先使用。擁有相同躍點數的成員把流量進行負載均衡。
進行負載均衡的成員之間擁有較高比重的成員將會被分配到更多流量。
名稱允許" +"包括 A-Z、a-z、0-9、_ 但是不能有空格。名稱應該在 15 個字元以內
策略不應" +"該與介面、成員、規則中的任意一個設定項使用相同的名稱" + +msgid "Policy" +msgstr "策略" + +msgid "Policy assigned" +msgstr "分配的策略" + +msgid "Protocol" +msgstr "通訊協議" + +msgid "Recovery interval" +msgstr "故障恢復間隔" + +msgid "Routing table %s for interface %s found" +msgstr "找到路由表 %s,為介面 %s" + +msgid "Routing table %s for interface %s not found" +msgstr "沒有找到路由表 %s,為介面 %s" + +msgid "Rule" +msgstr "規則" + +msgid "Rules" +msgstr "規則" + +msgid "" +"Rules specify which traffic will use a particular MWAN policy
Rules are " +"based on IP address, port or protocol
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
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
Names may contain characters A-Z, a-" +"z, 0-9, _ and no spaces
Rules may not share the same name as configured " +"interfaces, members or policies" +msgstr "" +"規則指定哪些流量將使用特定的 MWAN 策略
規則基於 IP 位址,埠或協議
" +"規則從上到下匹配
匹配規則以下的規則被忽略
不符合任何規則的流量將使" +"用主路由表進行路由
目的地為已知(非預設)網路的流量由主路由表處理
" +"流量符合規則,但該策略的所有 WAN 介面關閉後都會被失效
名稱可包含字元 A-" +"Z,a-z,0-9,_ 和空格
規則不能與配置的介面、成員或策略共享相同的名稱" + +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\".
The file is also preserved during sysupgrade.

Notes:
This " +"file is interpreted as a shell script.
The first line of the script " +"must be "#!/bin/sh" without quotes.
Lines beginning with # are " +"comments and are not executed.
Put your custom mwan3 action here, they " +"will
be executed with each netifd hotplug interface event
on " +"interfaces for which mwan3 is enabled.

There are three main " +"environment variables that are passed to this script.

$ACTION " +"
* \"ifup\" Is called by netifd and mwan3track
* \"ifdown\" Is " +"called by netifd and mwan3track
* \"connected\" Is only called by " +"mwan3track if tracking was successful
* \"disconnected\" Is only " +"called by mwan3track if tracking has failed
$INTERFACE Name of the " +"interface which went up or down (e.g. \"wan\" or \"wwan\")
$DEVICE " +"Physical device name which interface went up or down (e.g. \"eth0\" or " +"\"wwan0\")

" +msgstr "" +"這裡允許您修改“/etc/mwan3.user”的內容。
該檔案在 sysupgrade 期間也會保" +"留。

注意:
該檔案會作為 shell 指令碼解釋。
指令碼的第一" +"行必須是 "#!/bin/sh",不帶引號。
以 # 開頭的行是註釋,不會執行。" +"
將您的自定義 mwan3 動作放在這裡,他們將
在啟用 mwan3 的介面上
在 netifd hotplug 介面事件時執行。

有三個主要的環境變數傳遞給這個" +"指令碼。

$ACTION “ifup”或“ifdown”
$INTERFACE 啟動或停止的介面" +"名(例如“wan”或“wwan”)
$DEVICE 啟動或停止介面的物理裝置名(例" +"如“eth0”或“wwan0”)

" + +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\".
The file is also preserved during sysupgrade.

Notes:
This file is interpreted as a shell script.
The first line of the " +#~ "script must be "#!/bin/sh" without quotes.
Lines beginning " +#~ "with # are comments and are not executed.
Put your custom mwan3 " +#~ "action here, they will
be executed with each netifd hotplug " +#~ "interface event
on interfaces for which mwan3 is enabled.

There are three main environment variables that are passed to this " +#~ "script.

$ACTION Either \"ifup\" or \"ifdown\"
$INTERFACE " +#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan" +#~ "\")
$DEVICE Physical device name which interface went up or down (e." +#~ "g. \"eth0\" or \"wwan0\")

" +#~ msgstr "" +#~ "這裡允許您修改“/etc/mwan3.user”的內容。
該檔案在 sysupgrade 期間也會" +#~ "保留。

注意:
該檔案會作為 shell 指令碼解釋。
指令碼" +#~ "的第一行必須是"#!/bin/sh",不帶引號。
以#開頭的行是註釋,不會" +#~ "執行。
將您的自定義 mwan3 動作放在這裡,他們將
在啟用 mwan3 的介" +#~ "面上
在 netifd hotplug 介面事件時執行。

有三個主要的環境變" +#~ "數傳遞給這個指令碼。

$ACTION “ifup”或“ifdown”
$INTERFACE " +#~ "啟動或停止的介面名(例如“wan”或“wwan”)
$DEVICE 啟動或停止介面的物理" +#~ "裝置名(例如“eth0”或“wwan0”)

" + +#~ 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
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
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
Names may contain characters A-Z, a-z, 0-9, _ and " +#~ "no spaces
Rules may not share the same name as configured " +#~ "interfaces, members or policies" +#~ msgstr "" +#~ "“規則”基於 IP 位址、協議、埠把流量劃分到指定的“策略”中。
規則按照從上" +#~ "到下的順序進行匹配。除了第一條能夠匹配一次通訊的規則以外,其它規則將被忽" +#~ "略。不匹配任何規則的通訊將會由系統預設路由表進行。
來自已知的網路的轉" +#~ "發流量由系統預設路由表接手,然後 MWAN 從中匹配出相應的流量並轉移到 MWAN 自" +#~ "己的路由表。但是所有被劃分到一個無法使用的策略的流量將會無法正常進行路由。" +#~ "
名稱允許包括A-Z、a-z、0-9、_ 但是不能有空格。
規則不應該與接" +#~ "口、成員、策略中的任意一個設定項使用相同的名稱" + +#~ 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
This is useful for running system commands and/or scripts " +#~ "based on interface ifup or ifdown hotplug events

Notes:
The first line of the script must be "#!/bin/sh" without " +#~ "quotes
Lines beginning with # are comments and are not executed

Available variables:
$ACTION is the hotplug event (ifup, " +#~ "ifdown)
$INTERFACE is the interface name (wan1, wan2, etc.)
" +#~ "$DEVICE is the device name attached to the interface (eth0.1, eth1, etc.)" +#~ msgstr "" +#~ "這裡允許您修改 /etc/hotplug.d/iface/16-mwancustom 的內容
這可以在接" +#~ "口 ifup 或 ifdown Hotplug 事件時執行系統指令或指令碼

注意:
指令碼的第一行必須是 "#!/bin/sh" 不含引號
以#開頭的行是註" +#~ "釋,不會執行

可用變數:
$ACTION 是 Hotplug 事件(ifup, " +#~ "ifdown)
$INTERFACE 是介面名稱(wan1、wan2 等)
$DEVICE 是連線到" +#~ "介面的設備名稱 (eth0.1、eth1 等)" diff --git a/package/lean/luci-app-mwan3-alt/root/etc/uci-defaults/60_luci-mwan3 b/package/lean/luci-app-mwan3-alt/root/etc/uci-defaults/60_luci-mwan3 new file mode 100755 index 000000000..150ea5a3f --- /dev/null +++ b/package/lean/luci-app-mwan3-alt/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 diff --git a/package/lean/luci-app-syncdial/Makefile b/package/lean/luci-app-syncdial/Makefile new file mode 100755 index 000000000..232446870 --- /dev/null +++ b/package/lean/luci-app-syncdial/Makefile @@ -0,0 +1,17 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=Virtual WAN config generator +LUCI_DEPENDS:=+kmod-macvlan +luci-app-mwan3-alt +PKG_VERSION:=2.0 +PKG_RELEASE:=23 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature +#Makefile for syncdial diff --git a/package/lean/luci-app-syncdial/luasrc/controller/syncdial.lua b/package/lean/luci-app-syncdial/luasrc/controller/syncdial.lua new file mode 100644 index 000000000..bb5f48d75 --- /dev/null +++ b/package/lean/luci-app-syncdial/luasrc/controller/syncdial.lua @@ -0,0 +1,25 @@ +--[[ +Sync Dial Luci configuration page. +Copyright (C) 2015 GuoGuo +]]-- + +module("luci.controller.syncdial", package.seeall) + +function index() + + if not nixio.fs.access("/etc/config/syncdial") then + return + end + + local page + page = entry({"admin", "network", "syncdial"}, cbi("syncdial"), _("虚拟WAN")) + page.dependent = true + + page = entry({"admin", "network", "macvlan_redial"}, call("redial"), nil) + page.leaf = true + +end + +function redial() + os.execute("killall -9 pppd") +end diff --git a/package/lean/luci-app-syncdial/luasrc/model/cbi/syncdial.lua b/package/lean/luci-app-syncdial/luasrc/model/cbi/syncdial.lua new file mode 100644 index 000000000..95e540255 --- /dev/null +++ b/package/lean/luci-app-syncdial/luasrc/model/cbi/syncdial.lua @@ -0,0 +1,37 @@ +--[[ +Sync Dial Luci configuration page. +Copyright (C) 2015 GuoGuo +]]-- + +local fs = require "nixio.fs" + +local cmd = "mwan3 status | grep -c \"is online and tracking is active\"" +local shellpipe = io.popen(cmd,"r") +local ifnum = shellpipe:read("*a") +shellpipe:close() + + +m = Map("syncdial", translate("创建虚拟WAN接口"), + translatef("使用macvlan驱动创建多个虚拟WAN口。
当前在线接口数量:")..ifnum) + +s = m:section(TypedSection, "syncdial", translate(" ")) +s.anonymous = true + +switch = s:option(Flag, "enabled", "启用") +switch.rmempty = false + +--s:option(Flag, "force_redial", "强制全部重拨", "如果有接口掉线则强制所有接口下线重拨。").rmempty = false + +wannum = s:option(Value, "wannum", "虚拟WAN接口数量") +wannum.datatype = "range(0,20)" +wannum.optional = false + +s:option(Flag, "old_frame", "使用旧的macvlan创建方式").rmempty = false + +o = s:option(DummyValue, "_redial", "重新并发拨号") +o.template = "syncdial/redial_button" +o.width = "10%" + +return m + + diff --git a/package/lean/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm b/package/lean/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm new file mode 100644 index 000000000..e8c4f0739 --- /dev/null +++ b/package/lean/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm @@ -0,0 +1,17 @@ +<%+cbi/valueheader%> + + + + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-syncdial/root/bin/genwancfg b/package/lean/luci-app-syncdial/root/bin/genwancfg new file mode 100755 index 000000000..d24a0ea96 --- /dev/null +++ b/package/lean/luci-app-syncdial/root/bin/genwancfg @@ -0,0 +1,143 @@ +#!/bin/sh +#macvlan及PPPoE拨号接口配置批量自动生成脚本 +#Copyright (C) 2015 GuoGuo +. /lib/functions.sh + +#检测IP列表 +chk_ip_list="$(cat /tmp/resolv.conf.auto | grep nameserver | cut -d' ' -f2 | sort -u | tr '\n' ' ') 115.239.210.27 115.239.211.112 220.181.112.244 220.181.111.188 114.114.114.114 114.114.115.115" +fw_str="wan wan6" + +#添加MWAN负载均衡相关配置 +#$1:接口名称 +mwan_cfg_add() { + #gen mwan3_interface + uci set mwan3.${1}=interface + uci set mwan3.${1}.enabled=1 + uci set mwan3.${1}.count=1 + uci set mwan3.${1}.timeout=2 + uci set mwan3.${1}.interval=5 + uci set mwan3.${1}.down=3 + uci set mwan3.${1}.up=2 + for i in $chk_ip_list + do + uci add_list mwan3.${1}.track_ip="$i" + done + uci set mwan3.${1}.reliability=1 + #gen mwan3_member + uci set mwan3.${1}_m1_w1=member + uci set mwan3.${1}_m1_w1.interface=${1} + uci set mwan3.${1}_m1_w1.metric=1 + uci set mwan3.${1}_m1_w1.weight=1 + #gen mwan3_policy + uci add_list mwan3.balanced.use_member=${1}_m1_w1 +} + +#删除MWAN负载均衡相关配置 +#$1:接口名称 +mwan_cfg_del() { + uci del mwan3.${1} + uci del mwan3.${1}_m1_w1 + uci del_list mwan3.balanced.use_member=${1}_m1_w1 +} + +#添加macvlan设备 +#$1:设虚拟备名称 $2:原始设备名称 +macvlan_dev_add() { + uci set network.macvlandev_${1}=device + uci set network.macvlandev_${1}.name=${1} + uci set network.macvlandev_${1}.ifname=${2} + uci set network.macvlandev_${1}.type=macvlan +} + +#添加PPPoE接口 +#$1:接口名称 $2:设备名称 $3:账户 $4:密码 $5:网关跃点 +pppoe_if_add() { + #gen wan if + uci set network.${1}=interface + uci set network.${1}.ifname=${2} + uci set network.${1}.proto=pppoe + uci set network.${1}.username=${3} + uci set network.${1}.password=${4} + uci set network.${1}.metric=${5} + #gen firewall + fw_str="${fw_str} ${1}" +} + +apply_cfg() { + uci commit + /etc/init.d/network restart + killall pppconnectcheck + /etc/init.d/firewall restart + mwan3 restart +} + +general_config_load() { + config_load 'syncdial' + config_get_bool enabled 'config' 'enabled' + config_get_bool old_frame 'config' 'old_frame' + [ $enabled -eq 0 ] && { + echo "Disabled.Exit now." + apply_cfg + exit 1 + } + config_get wannum 'config' 'wannum' + + config_load 'network' + config_get pppoe_user 'wan' 'username' + config_get pppoe_password 'wan' 'password' + pppoe_ifname=$(uci get network.wan.ifname) +} + +check_remove_device() { + local devcfg=${1} + [ ${devcfg::11} == 'macvlandev_' ] && uci del network.${devcfg} +} + +check_remove_interface() { + local ifcfg=${1} + [ ${ifcfg::4} == 'vwan' ] && { + uci del network.${ifcfg} + mwan_cfg_del ${ifcfg} + } +} + +general_config_remove() { + config_load network + config_foreach check_remove_device 'device' + config_foreach check_remove_interface 'interface' + [ $(uci get network.wan.proto) == "none" ] && { + uci set network.wan.proto=pppoe + } + mwan_cfg_del 'wan' + uci set firewall.@zone[1].network="wan wan6" +} + + +general_config_remove +general_config_load + +uci set network.wan.metric=40 +[ $old_frame -eq 1 ] && { + uci set network.wan.proto=none + ifname=$(uci get network.wan.ifname) + for i in $(seq 1 $wannum) + do + ip link add link $ifname name macvlan$i type macvlan + ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$ifname/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i)) + ifconfig macvlan$i up + done +} +[ $old_frame -eq 0 ] && mwan_cfg_add wan + +for i in $(seq 1 $wannum) +do + [ $old_frame -eq 0 ] && macvlan_dev_add macvlan$i $pppoe_ifname + pppoe_if_add vwan$i macvlan$i $pppoe_user $pppoe_password $((40+$i)) + mwan_cfg_add vwan$i +done + +uci set firewall.@zone[1].network="$fw_str" + +apply_cfg + +return 0 diff --git a/package/lean/luci-app-syncdial/root/etc/config/syncdial b/package/lean/luci-app-syncdial/root/etc/config/syncdial new file mode 100644 index 000000000..9adeb2d70 --- /dev/null +++ b/package/lean/luci-app-syncdial/root/etc/config/syncdial @@ -0,0 +1,7 @@ +config syncdial 'config' + option 'enabled' '0' + option 'wannum' '2' + option 'dialchk' '0' + option 'dialnum' '1' + option 'dialwait' '25' + option 'old_frame' '1' diff --git a/package/lean/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate b/package/lean/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate new file mode 100644 index 000000000..426341fed --- /dev/null +++ b/package/lean/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate @@ -0,0 +1,16 @@ +#!/bin/sh +[ "$(uci get syncdial.config.enabled)" = "1" ] && \ + [ "$(uci get syncdial.config.old_frame)" = "1" ] && \ + [ "$DEVICE" = "$(uci get network.wan.ifname)" ] && \ + [ "$ACTION" = "ifup" ] && { + ifname=$(uci get network.wan.ifname) + wannum=$(uci get syncdial.config.wannum) + for i in $(seq 1 $wannum) + do + [ -d /sys/class/net/macvlan$i ] || { + ip link add link $ifname name macvlan$i type macvlan + ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$ifname/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i)) + ifconfig macvlan$i up + } + done +} diff --git a/package/lean/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial b/package/lean/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial new file mode 100755 index 000000000..5394164cc --- /dev/null +++ b/package/lean/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial @@ -0,0 +1,12 @@ +#!/bin/sh +touch /etc/config/syncdial + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@syncdial[-1] + add ucitrack syncdial + set ucitrack.@syncdial[-1].exec='/bin/genwancfg' + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/mwan3-alt/Makefile b/package/lean/mwan3-alt/Makefile new file mode 100644 index 000000000..4868ac8c0 --- /dev/null +++ b/package/lean/mwan3-alt/Makefile @@ -0,0 +1,68 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mwan3-alt +PKG_VERSION:=2.7.4 +PKG_RELEASE:=1 +PKG_MAINTAINER:=Florian Eckert +PKG_LICENSE:=GPLv2 + +include $(INCLUDE_DIR)/package.mk + +define Package/mwan3-alt + SECTION:=net + CATEGORY:=Network + SUBMENU:=Routing and Redirection + DEPENDS:= \ + +ip \ + +ipset \ + +iptables \ + +iptables-mod-conntrack-extra \ + +iptables-mod-ipopt \ + +jshn + TITLE:=Multiwan hotplug script with connection tracking support + MAINTAINER:=Florian Eckert + PKGARCH:=all +endef + +define Package/mwan3-alt/description +Hotplug script which makes configuration of multiple WAN interfaces simple +and manageable. With loadbalancing/failover support for up to 250 wan +interfaces, connection tracking and an easy to manage traffic ruleset. +endef + +define Package/mwan3-alt/conffiles +/etc/config/mwan3 +/etc/mwan3.user +endef + +define Build/Compile +endef + +define Package/mwan3-alt/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/rpcd restart +fi +exit 0 +endef + +define Package/mwan3-alt/postrm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/rpcd restart +fi +exit 0 +endef + +define Package/mwan3-alt/install +$(CP) ./files/* $(1) +endef + +$(eval $(call BuildPackage,mwan3-alt)) diff --git a/package/lean/mwan3-alt/files/etc/config/mwan3 b/package/lean/mwan3-alt/files/etc/config/mwan3 new file mode 100644 index 000000000..7f26f50b0 --- /dev/null +++ b/package/lean/mwan3-alt/files/etc/config/mwan3 @@ -0,0 +1,32 @@ + +config globals 'globals' + option mmx_mask '0x3F00' + option local_source 'lan' + option rtmon_interval '5' + +config interface 'wan' + option enabled '1' + list track_ip '114.114.114.114' + list track_ip '114.114.115.115' + option family 'ipv4' + option reliability '2' + option count '1' + option timeout '2' + option failure_latency '1000' + option recovery_latency '500' + option failure_loss '20' + option recovery_loss '5' + option interval '5' + option down '3' + option up '8' + +config rule 'https' + option sticky '1' + option dest_port '443' + option proto 'tcp' + option use_policy 'balanced' + +config rule 'default_rule' + option dest_ip '0.0.0.0/0' + option use_policy 'balanced' + diff --git a/package/lean/mwan3-alt/files/etc/hotplug.d/iface/14-mwan3 b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/14-mwan3 new file mode 100644 index 000000000..4f8e0be16 --- /dev/null +++ b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/14-mwan3 @@ -0,0 +1,48 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/mwan3/mwan3.sh +. /lib/functions/network.sh + +[ "$ACTION" = "ifup" -o "$ACTION" = "ifdown" ] || exit 1 +[ -n "$INTERFACE" ] || exit 2 + +if [ "$ACTION" = "ifup" ]; then + [ -n "$DEVICE" ] || exit 3 +fi + +config_load mwan3 +config_get_bool enabled globals 'enabled' '0' +[ ${enabled} -gt 0 ] || exit 0 + +config_get local_source globals local_source 'none' +[ "${local_source}" = "none" ] && { + exit 0 +} + +[ "${local_source}" = "$INTERFACE" ] || { + exit 0 +} + +mwan3_lock +src_ip=$(uci_get_state mwan3 globals src_ip) +[ "${src_ip}" != "" ] && { + ip route del default via "${src_ip}" dev lo 1>/dev/null 2>&1 + ip addr del "${src_ip}/32" dev lo 1>/dev/null 2>&1 +} + +sleep 1 + +[ "$ACTION" = "ifup" ] && { + network_get_ipaddr src_ip "${local_source}" + if [ "${src_ip}" = "" ]; then + $LOG warn "Unable to set source ip for own initiated traffic (${local_source})" + else + ip addr add "${src_ip}/32" dev lo + ip route add default via "${src_ip}" dev lo + uci_toggle_state mwan3 globals src_ip "${src_ip}" + fi +} +mwan3_unlock + +exit 0 diff --git a/package/lean/mwan3-alt/files/etc/hotplug.d/iface/15-mwan3 b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/15-mwan3 new file mode 100644 index 000000000..a02f88baa --- /dev/null +++ b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/15-mwan3 @@ -0,0 +1,95 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh +. /usr/share/libubox/jshn.sh + +[ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1 +[ -n "$INTERFACE" ] || exit 2 + +if [ "$ACTION" == "ifup" ]; then + [ -n "$DEVICE" ] || exit 3 +fi + +config_load mwan3 +config_get_bool enabled globals 'enabled' '0' +[ ${enabled} -gt 0 ] || exit 0 + +mwan3_lock +mwan3_init +mwan3_set_connected_iptables +mwan3_unlock + +config_get enabled $INTERFACE enabled 0 +config_get initial_state $INTERFACE initial_state "online" +[ "$enabled" == "1" ] || exit 0 + +if [ "$ACTION" == "ifup" ]; then + config_get family $INTERFACE family ipv4 + if [ "$family" = "ipv4" ]; then + ubus call network.interface.${INTERFACE}_4 status &>/dev/null + if [ "$?" -eq "0" ]; then + network_get_ipaddr src_ip ${INTERFACE}_4 + else + network_get_ipaddr src_ip ${INTERFACE} + fi + [ -n "$src_ip" ] || src_ip="0.0.0.0" + elif [ "$family" = "ipv6" ]; then + ubus call network.interface.${INTERFACE}_6 status &>/dev/null + if [ "$?" -eq "0" ]; then + network_get_ipaddr6 src_ip ${INTERFACE}_6 + else + network_get_ipaddr6 src_ip ${INTERFACE} + fi + [ -n "$src_ip" ] || src_ip="::" + fi +fi + +if [ "$initial_state" = "offline" ]; then + json_load "$(ubus call mwan3 status '{"section":"interfaces"}')" + json_select "interfaces" + json_select "${INTERFACE}" + json_get_var running running + json_get_var status status +else + status=online + running=1 +fi + +mwan3_lock +$LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})" + +case "$ACTION" in + ifup) + mwan3_set_general_rules + mwan3_set_general_iptables + mwan3_create_iface_iptables $INTERFACE $DEVICE + mwan3_create_iface_rules $INTERFACE $DEVICE + mwan3_create_iface_route $INTERFACE $DEVICE + if [ ${running} -eq 1 -a "${status}" = "online" ]; then + $LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})" + mwan3_set_iface_hotplug_state $INTERFACE "online" + mwan3_track $INTERFACE $DEVICE "online" "$src_ip" + mwan3_set_policies_iptables + mwan3_set_user_rules + mwan3_flush_conntrack $INTERFACE $DEVICE "ifup" + else + $LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})" + mwan3_set_iface_hotplug_state $INTERFACE "offline" + mwan3_track $INTERFACE $DEVICE "unknown" "$src_ip" + fi + ;; + ifdown) + mwan3_set_iface_hotplug_state $INTERFACE "offline" + mwan3_delete_iface_ipset_entries $INTERFACE + mwan3_track_signal $INTERFACE $DEVICE + mwan3_set_policies_iptables + mwan3_set_user_rules + mwan3_flush_conntrack $INTERFACE $DEVICE "ifdown" + ;; +esac + +mwan3_unlock + +exit 0 diff --git a/package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3 b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3 new file mode 100644 index 000000000..d2d148baf --- /dev/null +++ b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3 @@ -0,0 +1,17 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh + +config_load mwan3 +config_get_bool enabled globals 'enabled' '0' +[ ${enabled} -gt 0 ] || exit 0 + +if [ "$ACTION" == "ifup" ]; then + mwan3_lock + mwan3_rtmon + mwan3_unlock +fi + +exit 0 diff --git a/package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3-user b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3-user new file mode 100644 index 000000000..9372c736e --- /dev/null +++ b/package/lean/mwan3-alt/files/etc/hotplug.d/iface/16-mwan3-user @@ -0,0 +1,16 @@ +#!/bin/sh + +[ -f "/etc/mwan3.user" ] && { + . /lib/functions.sh + + config_load mwan3 + config_get_bool enabled globals 'enabled' '0' + [ ${enabled} -gt 0 ] || exit 0 + + config_get enabled "$INTERFACE" enabled 0 + [ "${enabled}" = "1" ] || exit 0 + env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \ + /bin/sh /etc/mwan3.user +} + +exit 0 diff --git a/package/lean/mwan3-alt/files/etc/init.d/mwan3 b/package/lean/mwan3-alt/files/etc/init.d/mwan3 new file mode 100755 index 000000000..2dccef363 --- /dev/null +++ b/package/lean/mwan3-alt/files/etc/init.d/mwan3 @@ -0,0 +1,20 @@ +#!/bin/sh /etc/rc.common + +START=19 + +reload() { + /usr/sbin/mwan3 restart +} + +boot() { + . /lib/config/uci.sh + uci_toggle_state mwan3 globals enabled "1" +} + +start() { + /usr/sbin/mwan3 start +} + +stop() { + /usr/sbin/mwan3 stop +} diff --git a/package/lean/mwan3-alt/files/etc/mwan3.user b/package/lean/mwan3-alt/files/etc/mwan3.user new file mode 100644 index 000000000..39989ab9b --- /dev/null +++ b/package/lean/mwan3-alt/files/etc/mwan3.user @@ -0,0 +1,16 @@ +#!/bin/sh +# +# This file is interpreted as shell script. +# Put your custom mwan3 action here, they will +# be executed with each netifd hotplug interface event +# on interfaces for which mwan3 is enabled. +# +# There are three main environment variables that are passed to this script. +# +# $ACTION +# Is called by netifd and mwan3track +# Is called by netifd and mwan3track +# Is only called by mwan3track if tracking was successful +# Is only called by mwan3track if tracking has failed +# $INTERFACE Name of the interface which went up or down (e.g. "wan" or "wwan") +# $DEVICE Physical device name which interface went up or down (e.g. "eth0" or "wwan0") diff --git a/package/lean/mwan3-alt/files/lib/mwan3/common.sh b/package/lean/mwan3-alt/files/lib/mwan3/common.sh new file mode 100644 index 000000000..1af129919 --- /dev/null +++ b/package/lean/mwan3-alt/files/lib/mwan3/common.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +get_uptime() { + local uptime=$(cat /proc/uptime) + echo "${uptime%%.*}" +} diff --git a/package/lean/mwan3-alt/files/lib/mwan3/mwan3.sh b/package/lean/mwan3-alt/files/lib/mwan3/mwan3.sh new file mode 100644 index 000000000..d0a47a523 --- /dev/null +++ b/package/lean/mwan3-alt/files/lib/mwan3/mwan3.sh @@ -0,0 +1,1030 @@ +#!/bin/sh + +IP4="ip -4" +IP6="ip -6" +IPS="ipset" +IPT4="iptables -t mangle -w" +IPT6="ip6tables -t mangle -w" +LOG="logger -t mwan3[$$] -p" +CONNTRACK_FILE="/proc/net/nf_conntrack" + +MWAN3_STATUS_DIR="/var/run/mwan3" +MWAN3TRACK_STATUS_DIR="/var/run/mwan3track" +MWAN3_INTERFACE_MAX="" +DEFAULT_LOWEST_METRIC=256 +MMX_MASK="" +MMX_DEFAULT="" +MMX_BLACKHOLE="" +MM_BLACKHOLE="" + +MMX_UNREACHABLE="" +MM_UNREACHABLE="" + +mwan3_rtmon_ipv4() +{ + local tid=1 + local idx=0 + local ret=1 + mkdir -p /tmp/mwan3rtmon + ($IP4 route list table main | grep -v "^default\|linkdown" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv4.main + while uci get mwan3.@interface[$idx] >/dev/null 2>&1 ; do + idx=$((idx+1)) + tid=$idx + [ "$(uci get mwan3.@interface[$((idx-1))].family)" = "ipv4" ] && { + if $IP4 route list table $tid | grep -q ^default; then + ($IP4 route list table $tid | grep -v "^default\|linkdown" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv4.$tid + cat /tmp/mwan3rtmon/ipv4.$tid | grep -v -x -F -f /tmp/mwan3rtmon/ipv4.main | while read line; do + $IP4 route del table $tid $line + done + cat /tmp/mwan3rtmon/ipv4.main | grep -v -x -F -f /tmp/mwan3rtmon/ipv4.$tid | while read line; do + $IP4 route add table $tid $line + done + fi + } + if [ "$(uci get mwan3.@interface[$((idx-1))].enabled)" = "1" ]; then + ret=0 + fi + done + rm -f /tmp/mwan3rtmon/ipv4.* + return $ret +} + +mwan3_rtmon_ipv6() +{ + local tid=1 + local idx=0 + local ret=1 + mkdir -p /tmp/mwan3rtmon + ($IP6 route list table main | grep -v "^default\|^::/0\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.main + while uci get mwan3.@interface[$idx] >/dev/null 2>&1 ; do + idx=$((idx+1)) + tid=$idx + [ "$(uci get mwan3.@interface[$((idx-1))].family)" = "ipv6" ] && { + if $IP6 route list table $tid | grep -q "^default\|^::/0"; then + ($IP6 route list table $tid | grep -v "^default\|^::/0\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.$tid + cat /tmp/mwan3rtmon/ipv6.$tid | grep -v -x -F -f /tmp/mwan3rtmon/ipv6.main | while read line; do + $IP6 route del table $tid $line + done + cat /tmp/mwan3rtmon/ipv6.main | grep -v -x -F -f /tmp/mwan3rtmon/ipv6.$tid | while read line; do + $IP6 route add table $tid $line + done + fi + } + if [ "$(uci get mwan3.@interface[$((idx-1))].enabled)" = "1" ]; then + ret=0 + fi + done + rm -f /tmp/mwan3rtmon/ipv6.* + return $ret +} + +# counts how many bits are set to 1 +# n&(n-1) clears the lowest bit set to 1 +mwan3_count_one_bits() +{ + local count n + count=0 + n=$(($1)) + while [ "$n" -gt "0" ]; do + n=$((n&(n-1))) + count=$((count+1)) + done + echo $count +} + +# maps the 1st parameter so it only uses the bits allowed by the bitmask (2nd parameter) +# which means spreading the bits of the 1st parameter to only use the bits that are set to 1 in the 2nd parameter +# 0 0 0 0 0 1 0 1 (0x05) 1st parameter +# 1 0 1 0 1 0 1 0 (0xAA) 2nd parameter +# 1 0 1 result +mwan3_id2mask() +{ + local bit_msk bit_val result + bit_val=0 + result=0 + for bit_msk in $(seq 0 31); do + if [ $((($2>>bit_msk)&1)) = "1" ]; then + if [ $((($1>>bit_val)&1)) = "1" ]; then + result=$((result|(1< "${MWAN3_STATUS_DIR}/mmx_mask" + $LOG notice "Using firewall mask ${MMX_MASK}" + + bitcnt=$(mwan3_count_one_bits MMX_MASK) + mmdefault=$(((1< /dev/null; then + $IPT -N mwan3_ifaces_in + fi + + if ! $IPT -S mwan3_connected &> /dev/null; then + $IPT -N mwan3_connected + $IPS -! create mwan3_connected list:set + $IPT -A mwan3_connected -m set --match-set mwan3_connected dst -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + fi + + if ! $IPT -S mwan3_rules &> /dev/null; then + $IPT -N mwan3_rules + fi + + if ! $IPT -S mwan3_hook &> /dev/null; then + $IPT -N mwan3_hook + # do not mangle ipv6 ra service + if [ "$IPT" = "$IPT6" ]; then + $IPT6 -A mwan3_hook -p ipv6-icmp -m icmp6 --icmpv6-type 133 -j RETURN + $IPT6 -A mwan3_hook -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j RETURN + $IPT6 -A mwan3_hook -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j RETURN + $IPT6 -A mwan3_hook -p ipv6-icmp -m icmp6 --icmpv6-type 136 -j RETURN + $IPT6 -A mwan3_hook -p ipv6-icmp -m icmp6 --icmpv6-type 137 -j RETURN + fi + $IPT -A mwan3_hook -j CONNMARK --restore-mark --nfmask $MMX_MASK --ctmask $MMX_MASK + $IPT -A mwan3_hook -m mark --mark 0x0/$MMX_MASK -j mwan3_ifaces_in + $IPT -A mwan3_hook -m mark --mark 0x0/$MMX_MASK -j mwan3_connected + $IPT -A mwan3_hook -m mark --mark 0x0/$MMX_MASK -j mwan3_rules + $IPT -A mwan3_hook -j CONNMARK --save-mark --nfmask $MMX_MASK --ctmask $MMX_MASK + $IPT -A mwan3_hook -m mark ! --mark $MMX_DEFAULT/$MMX_MASK -j mwan3_connected + fi + + if ! $IPT -S PREROUTING | grep mwan3_hook &> /dev/null; then + $IPT -A PREROUTING -j mwan3_hook + fi + + if ! $IPT -S OUTPUT | grep mwan3_hook &> /dev/null; then + $IPT -A OUTPUT -j mwan3_hook + fi + done +} + +mwan3_create_iface_iptables() +{ + local id family + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + $IPS -! create mwan3_connected list:set + + if ! $IPT4 -S mwan3_ifaces_in &> /dev/null; then + $IPT4 -N mwan3_ifaces_in + fi + + if ! $IPT4 -S mwan3_iface_in_$1 &> /dev/null; then + $IPT4 -N mwan3_iface_in_$1 + fi + + $IPT4 -F mwan3_iface_in_$1 + $IPT4 -A mwan3_iface_in_$1 -i $2 -m set --match-set mwan3_connected src -m mark --mark 0x0/$MMX_MASK -m comment --comment "default" -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + $IPT4 -A mwan3_iface_in_$1 -i $2 -m mark --mark 0x0/$MMX_MASK -m comment --comment "$1" -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + $IPT4 -D mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_$1 &> /dev/null + $IPT4 -A mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_$1 + fi + + if [ "$family" == "ipv6" ]; then + $IPS -! create mwan3_connected_v6 hash:net family inet6 + + if ! $IPT6 -S mwan3_ifaces_in &> /dev/null; then + $IPT6 -N mwan3_ifaces_in + fi + + if ! $IPT6 -S mwan3_iface_in_$1 &> /dev/null; then + $IPT6 -N mwan3_iface_in_$1 + fi + + $IPT6 -F mwan3_iface_in_$1 + $IPT6 -A mwan3_iface_in_$1 -i $2 -m set --match-set mwan3_connected_v6 src -m mark --mark 0x0/$MMX_MASK -m comment --comment "default" -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + $IPT6 -A mwan3_iface_in_$1 -i $2 -m mark --mark 0x0/$MMX_MASK -m comment --comment "$1" -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + $IPT6 -D mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_$1 &> /dev/null + $IPT6 -A mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_$1 + fi +} + +mwan3_delete_iface_iptables() +{ + config_get family $1 family ipv4 + + if [ "$family" == "ipv4" ]; then + + $IPT4 -D mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_$1 &> /dev/null + $IPT4 -F mwan3_iface_in_$1 &> /dev/null + $IPT4 -X mwan3_iface_in_$1 &> /dev/null + fi + + if [ "$family" == "ipv6" ]; then + + $IPT6 -D mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_$1 &> /dev/null + $IPT6 -F mwan3_iface_in_$1 &> /dev/null + $IPT6 -X mwan3_iface_in_$1 &> /dev/null + fi +} + +mwan3_create_iface_route() +{ + local id route_args metric + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + if ubus call network.interface.${1}_4 status &>/dev/null; then + network_get_gateway route_args ${1}_4 + else + network_get_gateway route_args $1 + fi + + if [ -n "$route_args" -a "$route_args" != "0.0.0.0" ]; then + route_args="via $route_args" + else + route_args="" + fi + + network_get_metric metric $1 + if [ -n "$metric" -a "$metric" != "0" ]; then + route_args="$route_args metric $metric" + fi + + $IP4 route flush table $id + $IP4 route add table $id default $route_args dev $2 + mwan3_rtmon_ipv4 + fi + + if [ "$family" == "ipv6" ]; then + if ubus call network.interface.${1}_6 status &>/dev/null; then + network_get_gateway6 route_args ${1}_6 + else + network_get_gateway6 route_args $1 + fi + + if [ -n "$route_args" -a "$route_args" != "::" ]; then + route_args="via $route_args" + else + route_args="" + fi + + network_get_metric metric $1 + if [ -n "$metric" -a "$metric" != "0" ]; then + route_args="$route_args metric $metric" + fi + + $IP6 route flush table $id + $IP6 route add table $id default $route_args dev $2 + mwan3_rtmon_ipv6 + fi +} + +mwan3_delete_iface_route() +{ + local id + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + $IP4 route flush table $id + fi + + if [ "$family" == "ipv6" ]; then + $IP6 route flush table $id + fi +} + +mwan3_create_iface_rules() +{ + local id family + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP4 rule del pref $(($id+1000)) + done + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP4 rule del pref $(($id+2000)) + done + + $IP4 rule add pref $(($id+1000)) iif $2 lookup $id + $IP4 rule add pref $(($id+2000)) fwmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK lookup $id + fi + + if [ "$family" == "ipv6" ]; then + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP6 rule del pref $(($id+1000)) + done + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP6 rule del pref $(($id+2000)) + done + + $IP6 rule add pref $(($id+1000)) iif $2 lookup $id + $IP6 rule add pref $(($id+2000)) fwmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK lookup $id + fi +} + +mwan3_delete_iface_rules() +{ + local id family + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP4 rule del pref $(($id+1000)) + done + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP4 rule del pref $(($id+2000)) + done + fi + + if [ "$family" == "ipv6" ]; then + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP6 rule del pref $(($id+1000)) + done + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP6 rule del pref $(($id+2000)) + done + fi +} + +mwan3_delete_iface_ipset_entries() +{ + local id setname entry + + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + for setname in $(ipset -n list | grep ^mwan3_sticky_); do + for entry in $(ipset list $setname | grep "$(echo $(mwan3_id2mask id MMX_MASK) | awk '{ printf "0x%08x", $1; }')" | cut -d ' ' -f 1); do + $IPS del $setname $entry + done + done +} + +mwan3_rtmon() +{ + pid="$(pgrep -f mwan3rtmon)" + if [ "${pid}" != "" ]; then + kill -USR1 "${pid}" + else + [ -x /usr/sbin/mwan3rtmon ] && /usr/sbin/mwan3rtmon & + fi +} + +mwan3_track() +{ + local track_ip track_ips pid + + mwan3_list_track_ips() + { + track_ips="$track_ips $1" + } + config_list_foreach $1 track_ip mwan3_list_track_ips + + for pid in $(pgrep -f "mwan3track $1 $2"); do + kill -TERM "$pid" > /dev/null 2>&1 + sleep 1 + kill -KILL "$pid" > /dev/null 2>&1 + done + if [ -n "$track_ips" ]; then + [ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track "$1" "$2" "$3" "$4" $track_ips & + fi +} + +mwan3_track_signal() +{ + local pid + + pid="$(pgrep -f "mwan3track $1 $2")" + [ "${pid}" != "" ] && { + kill -USR1 "${pid}" + } +} + +mwan3_set_policy() +{ + local iface_count id iface family metric probability weight device + + config_get iface $1 interface + config_get metric $1 metric 1 + config_get weight $1 weight 1 + + [ -n "$iface" ] || return 0 + network_get_device device $iface + [ "$metric" -gt $DEFAULT_LOWEST_METRIC ] && $LOG warn "Member interface $iface has >$DEFAULT_LOWEST_METRIC metric. Not appending to policy" && return 0 + + mwan3_get_iface_id id $iface + + [ -n "$id" ] || return 0 + + config_get family $iface family ipv4 + + if [ "$family" == "ipv4" ]; then + + if [ "$(mwan3_get_iface_hotplug_state $iface)" = "online" ]; then + if [ "$metric" -lt "$lowest_metric_v4" ]; then + + total_weight_v4=$weight + $IPT4 -F mwan3_policy_$policy + $IPT4 -A mwan3_policy_$policy -m mark --mark 0x0/$MMX_MASK -m comment --comment "$iface $weight $weight" -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + lowest_metric_v4=$metric + + elif [ "$metric" -eq "$lowest_metric_v4" ]; then + + total_weight_v4=$(($total_weight_v4+$weight)) + probability=$(($weight*1000/$total_weight_v4)) + + if [ "$probability" -lt 10 ]; then + probability="0.00$probability" + elif [ $probability -lt 100 ]; then + probability="0.0$probability" + elif [ $probability -lt 1000 ]; then + probability="0.$probability" + else + probability="1" + fi + + probability="-m statistic --mode random --probability $probability" + + $IPT4 -I mwan3_policy_$policy -m mark --mark 0x0/$MMX_MASK $probability -m comment --comment "$iface $weight $total_weight_v4" -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + fi + else + [ -n "$device" ] && { + $IPT4 -S mwan3_policy_$policy | grep -q '.*--comment ".* [0-9]* [0-9]*"' || \ + $IPT4 -I mwan3_policy_$policy -o $device -m mark --mark 0x0/$MMX_MASK -m comment --comment "out $iface $device" -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + } + fi + fi + + if [ "$family" == "ipv6" ]; then + + if [ "$(mwan3_get_iface_hotplug_state $iface)" = "online" ]; then + if [ "$metric" -lt "$lowest_metric_v6" ]; then + + total_weight_v6=$weight + $IPT6 -F mwan3_policy_$policy + $IPT6 -A mwan3_policy_$policy -m mark --mark 0x0/$MMX_MASK -m comment --comment "$iface $weight $weight" -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + lowest_metric_v6=$metric + + elif [ "$metric" -eq "$lowest_metric_v6" ]; then + + total_weight_v6=$(($total_weight_v6+$weight)) + probability=$(($weight*1000/$total_weight_v6)) + + if [ "$probability" -lt 10 ]; then + probability="0.00$probability" + elif [ $probability -lt 100 ]; then + probability="0.0$probability" + elif [ $probability -lt 1000 ]; then + probability="0.$probability" + else + probability="1" + fi + + probability="-m statistic --mode random --probability $probability" + + $IPT6 -I mwan3_policy_$policy -m mark --mark 0x0/$MMX_MASK $probability -m comment --comment "$iface $weight $total_weight_v6" -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + fi + else + [ -n "$device" ] && { + $IPT6 -S mwan3_policy_$policy | grep -q '.*--comment ".* [0-9]* [0-9]*"' || \ + $IPT6 -I mwan3_policy_$policy -o $device -m mark --mark 0x0/$MMX_MASK -m comment --comment "out $iface $device" -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + } + fi + fi +} + +mwan3_create_policies_iptables() +{ + local last_resort lowest_metric_v4 lowest_metric_v6 total_weight_v4 total_weight_v6 policy IPT + + policy="$1" + + config_get last_resort $1 last_resort unreachable + + if [ "$1" != $(echo "$1" | cut -c1-15) ]; then + $LOG warn "Policy $1 exceeds max of 15 chars. Not setting policy" && return 0 + fi + + for IPT in "$IPT4" "$IPT6"; do + + if ! $IPT -S mwan3_policy_$1 &> /dev/null; then + $IPT -N mwan3_policy_$1 + fi + + $IPT -F mwan3_policy_$1 + + case "$last_resort" in + blackhole) + $IPT -A mwan3_policy_$1 -m mark --mark 0x0/$MMX_MASK -m comment --comment "blackhole" -j MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK + ;; + default) + $IPT -A mwan3_policy_$1 -m mark --mark 0x0/$MMX_MASK -m comment --comment "default" -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + ;; + *) + $IPT -A mwan3_policy_$1 -m mark --mark 0x0/$MMX_MASK -m comment --comment "unreachable" -j MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK + ;; + esac + done + + lowest_metric_v4=$DEFAULT_LOWEST_METRIC + total_weight_v4=0 + + lowest_metric_v6=$DEFAULT_LOWEST_METRIC + total_weight_v6=0 + + config_list_foreach $1 use_member mwan3_set_policy +} + +mwan3_set_policies_iptables() +{ + config_foreach mwan3_create_policies_iptables policy +} + +mwan3_set_sticky_iptables() +{ + local id iface + + for iface in $($IPT4 -S $policy | cut -s -d'"' -f2 | awk '{print $1}'); do + + if [ "$iface" == "$1" ]; then + + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + for IPT in "$IPT4" "$IPT6"; do + if [ -n "$($IPT -S mwan3_iface_in_$1 2> /dev/null)" ]; then + $IPT -I mwan3_rule_$rule -m mark --mark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK -m set ! --match-set mwan3_sticky_$rule src,src -j MARK --set-xmark 0x0/$MMX_MASK + $IPT -I mwan3_rule_$rule -m mark --mark 0/$MMX_MASK -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + fi + done + fi + done +} + +mwan3_set_user_iptables_rule() +{ + local ipset family proto policy src_ip src_port sticky dest_ip dest_port use_policy timeout rule policy IPT + + rule="$1" + + config_get sticky $1 sticky 0 + config_get timeout $1 timeout 600 + config_get ipset $1 ipset + config_get proto $1 proto all + config_get src_ip $1 src_ip 0.0.0.0/0 + config_get src_port $1 src_port 0:65535 + config_get dest_ip $1 dest_ip 0.0.0.0/0 + config_get dest_port $1 dest_port 0:65535 + config_get use_policy $1 use_policy + config_get family $1 family any + + if [ "$1" != $(echo "$1" | cut -c1-15) ]; then + $LOG warn "Rule $1 exceeds max of 15 chars. Not setting rule" && return 0 + fi + + if [ -n "$ipset" ]; then + ipset="-m set --match-set $ipset dst" + fi + + if [ -n "$use_policy" ]; then + if [ "$use_policy" == "default" ]; then + policy="MARK --set-xmark $MMX_DEFAULT/$MMX_MASK" + elif [ "$use_policy" == "unreachable" ]; then + policy="MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK" + elif [ "$use_policy" == "blackhole" ]; then + policy="MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK" + else + if [ "$sticky" -eq 1 ]; then + + policy="mwan3_policy_$use_policy" + + for IPT in "$IPT4" "$IPT6"; do + if ! $IPT -S $policy &> /dev/null; then + $IPT -N $policy + fi + + if ! $IPT -S mwan3_rule_$1 &> /dev/null; then + $IPT -N mwan3_rule_$1 + fi + + $IPT -F mwan3_rule_$1 + done + + $IPS -! create mwan3_sticky_v4_$rule hash:ip,mark markmask $MMX_MASK timeout $timeout + $IPS -! create mwan3_sticky_v6_$rule hash:ip,mark markmask $MMX_MASK timeout $timeout family inet6 + $IPS -! create mwan3_sticky_$rule list:set + $IPS -! add mwan3_sticky_$rule mwan3_sticky_v4_$rule + $IPS -! add mwan3_sticky_$rule mwan3_sticky_v6_$rule + + config_foreach mwan3_set_sticky_iptables interface + + for IPT in "$IPT4" "$IPT6"; do + $IPT -A mwan3_rule_$1 -m mark --mark 0/$MMX_MASK -j $policy + $IPT -A mwan3_rule_$1 -m mark ! --mark 0xfc00/0xfc00 -j SET --del-set mwan3_sticky_$rule src,src + $IPT -A mwan3_rule_$1 -m mark ! --mark 0xfc00/0xfc00 -j SET --add-set mwan3_sticky_$rule src,src + done + + policy="mwan3_rule_$1" + else + policy="mwan3_policy_$use_policy" + + for IPT in "$IPT4" "$IPT6"; do + if ! $IPT -S $policy &> /dev/null; then + $IPT -N $policy + fi + done + + fi + fi + + if [ "$family" == "any" ]; then + + for IPT in "$IPT4" "$IPT6"; do + case $proto in + tcp|udp) + $IPT -A mwan3_rules -p $proto -s $src_ip -d $dest_ip $ipset -m multiport --sports $src_port -m multiport --dports $dest_port -m mark --mark 0/$MMX_MASK -m comment --comment "$1" -j $policy &> /dev/null + ;; + *) + $IPT -A mwan3_rules -p $proto -s $src_ip -d $dest_ip $ipset -m mark --mark 0/$MMX_MASK -m comment --comment "$1" -j $policy &> /dev/null + ;; + esac + done + + elif [ "$family" == "ipv4" ]; then + + case $proto in + tcp|udp) + $IPT4 -A mwan3_rules -p $proto -s $src_ip -d $dest_ip $ipset -m multiport --sports $src_port -m multiport --dports $dest_port -m mark --mark 0/$MMX_MASK -m comment --comment "$1" -j $policy &> /dev/null + ;; + *) + $IPT4 -A mwan3_rules -p $proto -s $src_ip -d $dest_ip $ipset -m mark --mark 0/$MMX_MASK -m comment --comment "$1" -j $policy &> /dev/null + ;; + esac + + elif [ "$family" == "ipv6" ]; then + + case $proto in + tcp|udp) + $IPT6 -A mwan3_rules -p $proto -s $src_ip -d $dest_ip $ipset -m multiport --sports $src_port -m multiport --dports $dest_port -m mark --mark 0/$MMX_MASK -m comment --comment "$1" -j $policy &> /dev/null + ;; + *) + $IPT6 -A mwan3_rules -p $proto -s $src_ip -d $dest_ip $ipset -m mark --mark 0/$MMX_MASK -m comment --comment "$1" -j $policy &> /dev/null + ;; + esac + fi + fi +} + +mwan3_set_user_rules() +{ + local IPT + + for IPT in "$IPT4" "$IPT6"; do + + if ! $IPT -S mwan3_rules &> /dev/null; then + $IPT -N mwan3_rules + fi + + $IPT -F mwan3_rules + done + + config_foreach mwan3_set_user_iptables_rule rule +} + +mwan3_set_iface_hotplug_state() { + local iface=$1 + local state=$2 + + echo -n $state > $MWAN3_STATUS_DIR/iface_state/$iface +} + +mwan3_get_iface_hotplug_state() { + local iface=$1 + + cat $MWAN3_STATUS_DIR/iface_state/$iface 2>/dev/null || echo "unknown" +} + +mwan3_report_iface_status() +{ + local device result track_ips tracking IP IPT + + mwan3_get_iface_id id $1 + network_get_device device $1 + config_get enabled "$1" enabled 0 + config_get family "$1" family ipv4 + + if [ "$family" == "ipv4" ]; then + IP="$IP4" + IPT="$IPT4" + fi + + if [ "$family" == "ipv6" ]; then + IP="$IP6" + IPT="$IPT6" + fi + + if [ -z "$id" -o -z "$device" ]; then + result="unknown" + elif [ -n "$($IP rule | awk '$1 == "'$(($id+1000)):'"')" -a -n "$($IP rule | awk '$1 == "'$(($id+2000)):'"')" -a -n "$($IPT -S mwan3_iface_in_$1 2> /dev/null)" -a -n "$($IP route list table $id default dev $device 2> /dev/null)" ]; then + result="$(mwan3_get_iface_hotplug_state $1)" + elif [ -n "$($IP rule | awk '$1 == "'$(($id+1000)):'"')" -o -n "$($IP rule | awk '$1 == "'$(($id+2000)):'"')" -o -n "$($IPT -S mwan3_iface_in_$1 2> /dev/null)" -o -n "$($IP route list table $id default dev $device 2> /dev/null)" ]; then + result="error" + elif [ "$enabled" == "1" ]; then + result="offline" + else + result="disabled" + fi + + mwan3_list_track_ips() + { + track_ips="$1 $track_ips" + } + config_list_foreach $1 track_ip mwan3_list_track_ips + + if [ -n "$track_ips" ]; then + if [ -n "$(pgrep -f "mwan3track $1 $device")" ]; then + tracking="active" + else + tracking="down" + fi + else + tracking="not enabled" + fi + + echo " interface $1 is $result and tracking is $tracking" +} + +mwan3_report_policies_v4() +{ + local percent policy share total_weight weight iface + + for policy in $($IPT4 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do + echo "$policy:" | sed 's/mwan3_policy_//' + + [ -n "$total_weight" ] || total_weight=$($IPT4 -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | head -1 | awk '{print $3}') + + if [ ! -z "${total_weight##*[!0-9]*}" ]; then + for iface in $($IPT4 -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '{print $1}'); do + weight=$($IPT4 -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '$1 == "'$iface'"' | awk '{print $2}') + percent=$(($weight*100/$total_weight)) + echo " $iface ($percent%)" + done + else + echo " $($IPT4 -S $policy | grep -v '.*--comment "out .*" .*$' | sed '/.*--comment \([^ ]*\) .*$/!d;s//\1/;q')" + fi + + unset total_weight + + echo -e + done +} + +mwan3_report_policies_v6() +{ + local percent policy share total_weight weight iface + + for policy in $($IPT6 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do + echo "$policy:" | sed 's/mwan3_policy_//' + + [ -n "$total_weight" ] || total_weight=$($IPT6 -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | head -1 | awk '{print $3}') + + if [ ! -z "${total_weight##*[!0-9]*}" ]; then + for iface in $($IPT6 -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '{print $1}'); do + weight=$($IPT6 -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '$1 == "'$iface'"' | awk '{print $2}') + percent=$(($weight*100/$total_weight)) + echo " $iface ($percent%)" + done + else + echo " $($IPT6 -S $policy | grep -v '.*--comment "out .*" .*$' | sed '/.*--comment \([^ ]*\) .*$/!d;s//\1/;q')" + fi + + unset total_weight + + echo -e + done +} + +mwan3_report_connected_v4() +{ + local address + + if [ -n "$($IPT4 -S mwan3_connected 2> /dev/null)" ]; then + for address in $($IPS list mwan3_connected_v4 | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do + echo " $address" + done + fi +} + +mwan3_report_connected_v6() +{ + local address + + if [ -n "$($IPT6 -S mwan3_connected 2> /dev/null)" ]; then + for address in $($IPS list mwan3_connected_v6 | egrep '([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])'); do + echo " $address" + done + fi +} + +mwan3_report_rules_v4() +{ + if [ -n "$($IPT4 -S mwan3_rules 2> /dev/null)" ]; then + $IPT4 -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_/- /' | sed 's/mwan3_rule_/S /' + fi +} + +mwan3_report_rules_v6() +{ + if [ -n "$($IPT6 -S mwan3_rules 2> /dev/null)" ]; then + $IPT6 -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_/- /' | sed 's/mwan3_rule_/S /' + fi +} + +mwan3_flush_conntrack() +{ + local flush_conntrack + + config_get flush_conntrack $1 flush_conntrack never + + if [ -e "$CONNTRACK_FILE" ]; then + case $flush_conntrack in + ifup) + [ "$3" = "ifup" ] && { + echo f > ${CONNTRACK_FILE} + $LOG info "connection tracking flushed on interface $1 ($2) $3" + } + ;; + ifdown) + [ "$3" = "ifdown" ] && { + echo f > ${CONNTRACK_FILE} + $LOG info "connection tracking flushed on interface $1 ($2) $3" + } + ;; + always) + echo f > ${CONNTRACK_FILE} + $LOG info "connection tracking flushed on interface $1 ($2) $3" + ;; + never) + $LOG info "connection tracking not flushed on interface $1 ($2) $3" + ;; + esac + else + $LOG warning "connection tracking not enabled" + fi +} + +mwan3_track_clean() +{ + rm -rf "$MWAN3_STATUS_DIR/${1}" &> /dev/null + [ -d "$MWAN3_STATUS_DIR" ] && { + if [ -z "$(ls -A "$MWAN3_STATUS_DIR")" ]; then + rm -rf "$MWAN3_STATUS_DIR" + fi + } +} diff --git a/package/lean/mwan3-alt/files/usr/libexec/rpcd/mwan3 b/package/lean/mwan3-alt/files/usr/libexec/rpcd/mwan3 new file mode 100755 index 000000000..a9b31f222 --- /dev/null +++ b/package/lean/mwan3-alt/files/usr/libexec/rpcd/mwan3 @@ -0,0 +1,156 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /usr/share/libubox/jshn.sh +. /lib/mwan3/common.sh + +MWAN3TRACK_STATUS_DIR="/var/run/mwan3track" + +IPS="ipset" +IPT4="iptables -t mangle -w" +IPT6="ip6tables -t mangle -w" + +report_connected_v4() { + local address + + if [ -n "$($IPT4 -S mwan3_connected 2> /dev/null)" ]; then + for address in $($IPS list mwan3_connected_v4 | tail -n +8); do + json_add_string "" "${address}" + done + fi +} + +report_connected_v6() { + local address + + if [ -n "$($IPT6 -S mwan3_connected 2> /dev/null)" ]; then + for address in $($IPS list mwan3_connected_v6 | tail -n +8); do + json_add_string "" "${address}" + done + fi +} + +get_mwan3_status() { + local iface="${1}" + local iface_select="${2}" + local running="0" + local age=0 + local uptime=0 + local downtime=0 + local pid device time_p time_n time_u time_d + + network_get_device device $1 + + if [ "${iface}" = "${iface_select}" ] || [ "${iface_select}" = "" ]; then + pid="$(pgrep -f "mwan3track $iface $device")" + if [ "${pid}" != "" ]; then + running="1" + fi + + time_p="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TIME")" + [ -z "${time_p}" ] || { + time_n="$(get_uptime)" + let age=time_n-time_p + } + + time_u="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/UPTIME")" + [ -z "${time_u}" ] || [ "${time_u}" = "0" ] || { + time_n="$(get_uptime)" + let uptime=time_n-time_u + } + + time_d="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/DOWNTIME")" + [ -z "${time_d}" ] || [ "${time_d}" = "0" ] || { + time_n="$(get_uptime)" + let downtime=time_n-time_d + } + + json_add_object "${iface}" + json_add_int age "$age" + json_add_int uptime "${uptime}" + json_add_int downtime "${downtime}" + json_add_int "score" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/SCORE")" + json_add_int "lost" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOST")" + json_add_int "turn" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TURN")" + json_add_string "status" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS")" + json_add_boolean "running" "${running}" + json_add_array "track_ip" + for file in $MWAN3TRACK_STATUS_DIR/${iface}/*; do + track="${file#*/TRACK_}" + if [ "${track}" != "${file}" ]; then + json_add_object + json_add_string ip "${track}" + json_add_string status "$(cat "${file}")" + json_add_int latency "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LATENCY_${track}")" + json_add_int packetloss "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOSS_${track}")" + json_close_object + fi + done + json_close_array + json_close_object + fi +} + +main () { + + case "$1" in + list) + json_init + json_add_object "status" + json_add_string "section" "x" + json_add_string "interface" "x" + json_close_object + json_dump + ;; + call) + case "$2" in + status) + local section iface + read input; + json_load "$input" + json_get_var section section + json_get_var iface interface + + config_load mwan3 + json_init + case "$section" in + interfaces) + json_add_object interfaces + config_foreach get_mwan3_status interface "${iface}" + json_close_object + ;; + connected) + json_add_object connected + json_add_array ipv4 + report_connected_v4 + json_close_array + json_add_array ipv6 + report_connected_v6 + json_close_array + json_close_object + ;; + *) + # interfaces + json_add_object interfaces + config_foreach get_mwan3_status interface + json_close_object + # connected + json_add_object connected + json_add_array ipv4 + report_connected_v4 + json_close_array + json_add_array ipv6 + report_connected_v6 + json_close_array + json_close_object + ;; + esac + json_dump + ;; + esac + ;; + esac +} + +main "$@" diff --git a/package/lean/mwan3-alt/files/usr/sbin/mwan3 b/package/lean/mwan3-alt/files/usr/sbin/mwan3 new file mode 100755 index 000000000..4ad3bc391 --- /dev/null +++ b/package/lean/mwan3-alt/files/usr/sbin/mwan3 @@ -0,0 +1,239 @@ +#!/bin/sh + +. /lib/functions.sh +. /usr/share/libubox/jshn.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh + +help() +{ + cat < Load rules and routes for specific interface + ifdown Unload rules and routes for specific interface + interfaces Show interfaces status + policies Show currently active policy + connected Show directly connected networks + rules Show active rules + status Show all status + +EOF +} + +ifdown() +{ + if [ -z "$1" ]; then + echo "Error: Expecting interface. Usage: mwan3 ifdown " && exit 0 + fi + + if [ -n "$2" ]; then + echo "Error: Too many arguments. Usage: mwan3 ifdown " && exit 0 + fi + + ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface + + kill $(pgrep -f "mwan3track $1 $2") &> /dev/null + mwan3_track_clean $1 +} + +ifup() +{ + local device enabled up l3_device status + + config_load mwan3 + config_get_bool enabled globals 'enabled' 0 + [ ${enabled} -gt 0 ] || { + echo "The service mwan3 is global disabled." + echo "Please execute \"/etc/init.d/mwan3 start\" first." + exit 1 + } + + if [ -z "$1" ]; then + echo "Expecting interface. Usage: mwan3 ifup " && exit 0 + fi + + if [ -n "$2" ]; then + echo "Too many arguments. Usage: mwan3 ifup " && exit 0 + fi + + config_get_bool enabled globals 'enabled' 0 + [ ${enabled} -gt 0 ] || { + echo "Warning: mwan3 is global disabled. Usage: /etc/init.d/mwan3 start" + exit 0 + } + + status=$(ubus -S call network.interface.$1 status) + [ -n "$status" ] && { + json_load $status + json_get_vars up l3_device + } + + config_get enabled "$1" enabled 0 + + + if [ "$up" = "1" ] \ + && [ -n "$l3_device" ] \ + && [ "$enabled" = "1" ]; then + ACTION=ifup INTERFACE=$1 DEVICE=$l3_device /sbin/hotplug-call iface + fi +} + +interfaces() +{ + config_load mwan3 + + echo "Interface status:" + config_foreach mwan3_report_iface_status interface + echo -e +} + +policies() +{ + echo "Current ipv4 policies:" + mwan3_report_policies_v4 + echo -e + echo "Current ipv6 policies:" + mwan3_report_policies_v6 + echo -e +} + +connected() +{ + echo "Directly connected ipv4 networks:" + mwan3_report_connected_v4 + echo -e + echo "Directly connected ipv6 networks:" + mwan3_report_connected_v6 + echo -e +} + +rules() +{ + echo "Active ipv4 user rules:" + mwan3_report_rules_v4 + echo -e + echo "Active ipv6 user rules:" + mwan3_report_rules_v6 + echo -e +} + +status() +{ + interfaces + policies + connected + rules +} + +start() +{ + local enabled src_ip local_source + + uci_toggle_state mwan3 globals enabled "1" + + config_get local_source globals local_source 'none' + [ "${local_source}" = "none" ] || { + src_ip=$(uci_get_state mwan3 globals src_ip) + [ "${src_ip}" != "" ] && { + ip route del default via "${src_ip}" dev lo 1>/dev/null 2>&1 + ip addr del "${src_ip}/32" dev lo 1>/dev/null 2>&1 + } + + network_get_ipaddr src_ip "${local_source}" + if [ "${src_ip}" = "" ]; then + $LOG warn "Unable to set source ip for own initiated traffic (${local_source})" + else + ip addr add "${src_ip}/32" dev lo + ip route add default via "${src_ip}" dev lo + uci_toggle_state mwan3 globals src_ip "${src_ip}" + fi + } + + config_foreach ifup interface +} + +stop() +{ + local ipset route rule table IP IPT pid src_ip + + for pid in $(pgrep -f "mwan3rtmon"); do + kill -TERM "$pid" > /dev/null 2>&1 + sleep 1 + kill -KILL "$pid" > /dev/null 2>&1 + done + + for pid in $(pgrep -f "mwan3track"); do + kill -TERM "$pid" > /dev/null 2>&1 + sleep 1 + kill -KILL "$pid" > /dev/null 2>&1 + done + + config_load mwan3 + config_foreach mwan3_track_clean interface + + for IP in "$IP4" "$IP6"; do + + for route in $(seq 1 $MWAN3_INTERFACE_MAX); do + $IP route flush table $route &> /dev/null + done + + for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do + $IP rule del pref $rule &> /dev/null + done + done + + for IPT in "$IPT4" "$IPT6"; do + + $IPT -D PREROUTING -j mwan3_hook &> /dev/null + $IPT -D OUTPUT -j mwan3_hook &> /dev/null + + for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do + $IPT -F $table &> /dev/null + done + + for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do + $IPT -X $table &> /dev/null + done + done + + for ipset in $($IPS -n list | grep mwan3_); do + $IPS -q destroy $ipset + done + + for ipset in $($IPS -n list | grep mwan3 | grep -E '_v4|_v6'); do + $IPS -q destroy $ipset + done + + mwan3_lock_clean + rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR + + src_ip=$(uci_get_state mwan3 globals src_ip) + [ "${src_ip}" = "" ] || { + ip route del default via "${src_ip}" dev lo 1>/dev/null 2>&1 + ip addr del "${src_ip}/32" dev lo 1>/dev/null 2>&1 + } + + uci_toggle_state mwan3 globals enabled "0" +} + +restart() { + stop + start +} + +case "$1" in + ifup|ifdown|interfaces|policies|connected|rules|status|start|stop|restart) + mwan3_init + $* + ;; + *) + help + ;; +esac + +exit 0 diff --git a/package/lean/mwan3-alt/files/usr/sbin/mwan3rtmon b/package/lean/mwan3-alt/files/usr/sbin/mwan3rtmon new file mode 100755 index 000000000..667d0cc87 --- /dev/null +++ b/package/lean/mwan3-alt/files/usr/sbin/mwan3rtmon @@ -0,0 +1,32 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/mwan3/mwan3.sh + +LOG="logger -t $(basename "$0")[$$] -p" + +clean_up() { + $LOG notice "Stopping mwan3rtmon..." + exit 0 +} + +rtchange() { + $LOG info "Detect rtchange event." +} + +main() { + local rtmon_interval + trap clean_up TERM + trap rtchange USR1 + + config_load mwan3 + config_get rtmon_interval globals rtmon_interval '5' + + sleep 3 + while mwan3_rtmon_ipv4 || mwan3_rtmon_ipv6; do + [ "$rtmon_interval" = "0" ] && break + sleep $rtmon_interval + done +} + +main "$@" diff --git a/package/lean/mwan3-alt/files/usr/sbin/mwan3track b/package/lean/mwan3-alt/files/usr/sbin/mwan3track new file mode 100755 index 000000000..420878472 --- /dev/null +++ b/package/lean/mwan3-alt/files/usr/sbin/mwan3track @@ -0,0 +1,259 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/mwan3/common.sh + +LOG="logger -t $(basename "$0")[$$] -p" +INTERFACE="" +DEVICE="" + +IFDOWN_EVENT=0 + +clean_up() { + $LOG notice "Stopping mwan3track for interface \"${INTERFACE}\"" + exit 0 +} + +if_down() { + $LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})" + IFDOWN_EVENT=1 +} + +validate_track_method() { + case "$1" in + ping) + which ping 1>/dev/null 2>&1 || { + $LOG warn "Missing ping. Please install iputils-ping package or enable ping util and recompile busybox." + return 1 + } + ;; + arping) + which arping 1>/dev/null 2>&1 || { + $LOG warn "Missing arping. Please install iputils-arping package." + return 1 + } + ;; + httping) + which httping 1>/dev/null 2>&1 || { + $LOG warn "Missing httping. Please install httping package." + return 1 + } + [ -n "$2" -a "$2" != "0.0.0.0" -a "$2" != "::" ] || { + $LOG warn "Cannot determine source IP for the interface which is required by httping." + return 1 + } + ;; + *) + $LOG warn "Unsupported tracking method: $track_method" + return 2 + ;; + esac +} + +main() { + local reliability count timeout interval failure_interval + local recovery_interval down up size + local keep_failure_interval check_quality failure_latency + local recovery_latency failure_loss recovery_loss + local max_ttl + + [ -z "$5" ] && echo "Error: should not be started manually" && exit 0 + + INTERFACE=$1 + DEVICE=$2 + STATUS=$3 + SRC_IP=$4 + mkdir -p /var/run/mwan3track/$1 + trap clean_up TERM + trap if_down USR1 + + config_load mwan3 + config_get track_method $1 track_method ping + validate_track_method $track_method $SRC_IP || { + track_method=ping + if validate_track_method $track_method; then + $LOG warn "Using ping to track interface $INTERFACE avaliability" + else + $LOG err "No track method avaliable" + exit 1 + fi + } + config_get reliability $1 reliability 1 + config_get count $1 count 1 + config_get timeout $1 timeout 4 + config_get interval $1 interval 10 + config_get down $1 down 5 + config_get up $1 up 5 + config_get size $1 size 56 + config_get max_ttl $1 max_ttl 60 + config_get failure_interval $1 failure_interval $interval + config_get_bool keep_failure_interval $1 keep_failure_interval 0 + config_get recovery_interval $1 recovery_interval $interval + config_get_bool check_quality $1 check_quality 0 + config_get failure_latency $1 failure_latency 1000 + config_get recovery_latency $1 recovery_latency 500 + config_get failure_loss $1 failure_loss 40 + config_get recovery_loss $1 recovery_loss 10 + + local score=$(($down+$up)) + local track_ips=$(echo $* | cut -d ' ' -f 5-99) + local host_up_count=0 + local lost=0 + local sleep_time=0 + local turn=0 + local result + local ping_result + local loss=0 + local latency=0 + + if [ "$STATUS" = "unknown" ]; then + echo "unknown" > /var/run/mwan3track/$1/STATUS + echo "0" > /var/run/mwan3track/$1/UPTIME + echo "$(get_uptime)" > /var/run/mwan3track/$1/DOWNTIME + score=0 + else + echo "online" > /var/run/mwan3track/$1/STATUS + echo "0" > /var/run/mwan3track/$1/DOWNTIME + echo "$(get_uptime)" > /var/run/mwan3track/$1/UPTIME + env -i ACTION="connected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface + fi + while true; do + + sleep_time=$interval + + for track_ip in $track_ips; do + if [ $host_up_count -lt $reliability ]; then + case "$track_method" in + ping) + if [ $check_quality -eq 0 ]; then + ping -I $DEVICE -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null + result=$? + else + ping_result="$(ping -I $DEVICE -c $count -W $timeout -s $size -t $max_ttl -q $track_ip | tail -2)" + loss="$(echo "$ping_result" | grep "packet loss" | cut -d "," -f3 | awk '{print $1}' | sed -e 's/%//')" + if [ "$loss" -eq 100 ]; then + latency=999999 + else + latency="$(echo "$ping_result" | grep -E 'rtt|round-trip' | cut -d "=" -f2 | cut -d "/" -f2 | cut -d "." -f1)" + fi + fi + ;; + arping) + arping -I $DEVICE -c $count -w $timeout -q $track_ip &> /dev/null + result=$? + ;; + httping) + httping -y $SRC_IP -c $count -t $timeout -q $track_ip &> /dev/null + result=$? + ;; + esac + if [ $check_quality -eq 0 ]; then + if [ $result -eq 0 ]; then + let host_up_count++ + echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip} + if [ $score -le $up ]; then + $LOG info "Check ($track_method) success for target \"$track_ip\" on interface $1 ($2)" + fi + else + let lost++ + echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip} + if [ $score -gt $up ]; then + $LOG info "Check ($track_method) failed for target \"$track_ip\" on interface $1 ($2)" + fi + fi + else + if [ "$loss" -ge "$failure_loss" -o "$latency" -ge "$failure_latency" ]; then + let lost++ + echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip} + echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip} + echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip} + + if [ $score -gt $up ]; then + $LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) failed for target \"$track_ip\" on interface $1 ($2)" + fi + elif [ "$loss" -le "$recovery_loss" -a "$latency" -le "$recovery_latency" ]; then + let host_up_count++ + echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip} + echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip} + echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip} + + if [ $score -le $up ]; then + $LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) success for target \"$track_ip\" on interface $1 ($2)" + fi + else + echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip} + fi + fi + else + echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip} + fi + done + + if [ $host_up_count -lt $reliability ]; then + let score-- + + if [ $score -lt $up ]; then + score=0 + [ ${keep_failure_interval} -eq 1 ] && { + sleep_time=$failure_interval + } + else + sleep_time=$failure_interval + fi + + if [ $score -eq $up ]; then + echo "offline" > /var/run/mwan3track/$1/STATUS + echo "0" > /var/run/mwan3track/$1/UPTIME + echo "$(get_uptime)" > /var/run/mwan3track/$1/DOWNTIME + $LOG notice "Interface $1 ($2) is offline" + env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface + env -i ACTION="disconnected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface + score=0 + fi + else + if [ $score -lt $(($down+$up)) ] && [ $lost -gt 0 ]; then + $LOG info "Lost $(($lost*$count)) ping(s) on interface $1 ($2)" + fi + + let score++ + lost=0 + + if [ $score -gt $up ]; then + echo "online" > /var/run/mwan3track/$1/STATUS + score=$(($down+$up)) + elif [ $score -le $up ]; then + sleep_time=$recovery_interval + fi + + if [ $score -eq $up ]; then + $LOG notice "Interface $1 ($2) is online" + echo "online" > /var/run/mwan3track/$1/STATUS + env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface + exit 0 + fi + fi + + let turn++ + mkdir -p "/var/run/mwan3track/${1}" + echo "${lost}" > /var/run/mwan3track/$1/LOST + echo "${score}" > /var/run/mwan3track/$1/SCORE + echo "${turn}" > /var/run/mwan3track/$1/TURN + echo "$(get_uptime)" > /var/run/mwan3track/$1/TIME + + host_up_count=0 + sleep "${sleep_time}" & + wait + + if [ "${IFDOWN_EVENT}" -eq 1 ]; then + echo "offline" > /var/run/mwan3track/$1/STATUS + echo "$(get_uptime)" > /var/run/mwan3track/$1/DOWNTIME + echo "0" > /var/run/mwan3track/$1/UPTIME + $LOG notice "Interface $1 ($2) is offline" + env -i ACTION="disconnected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface + score=0 + IFDOWN_EVENT=0 + fi + done +} + +main "$@"