Merge pull request #1855 from rosysong/nqos

luci-app-nft-qos: add new application
This commit is contained in:
Hannu Nyman 2018-11-07 16:54:07 +02:00 committed by GitHub
commit 14ad794925
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 966 additions and 0 deletions

View file

@ -0,0 +1,14 @@
#
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Qos over Nftables
LUCI_DEPENDS:=+nft-qos
include ../../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View file

@ -0,0 +1,51 @@
-- Copyright 2018 Rosy Song <rosysong@rosinson.com>
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.nft-qos", package.seeall)
function index()
if not nixio.fs.access("/etc/config/nft-qos") then
return
end
entry({"admin", "status", "realtime", "rate"},
template("nft-qos/rate"), _("Rate"), 5).leaf = true
entry({"admin", "status", "realtime", "rate_status"},
call("action_rate")).leaf = true
entry({"admin", "services", "nft-qos"}, cbi("nft-qos/nft-qos"),
_("Qos over Nftables"), 60)
end
function _action_rate(rv, n)
local c = io.popen("nft list chain inet nft-qos-monitor " .. n .. " 2>/dev/null")
if c then
for l in c:lines() do
local _, i, p, b = l:match('^%s+ip ([^%s]+) ([^%s]+) counter packets (%d+) bytes (%d+)')
if i and p and b then
-- handle expression
local r = {
rule = {
family = "inet",
table = "nft-qos-monitor",
chain = n,
handle = 0,
expr = {
{ match = { right = i } },
{ counter = { packets = p, bytes = b } }
}
}
}
rv[#rv + 1] = r
end
end
c:close()
end
end
function action_rate()
luci.http.prepare_content("application/json")
local data = { nftables = {} }
_action_rate(data.nftables, "upload")
_action_rate(data.nftables, "download")
luci.http.write_json(data)
end

View file

@ -0,0 +1,229 @@
-- Copyright 2018 Rosy Song <rosysong@rosinson.com>
-- Licensed to the public under the Apache License 2.0.
local uci = require("luci.model.uci").cursor()
local wa = require("luci.tools.webadmin")
local fs = require("nixio.fs")
local ipc = require("luci.ip")
local def_rate_dl = uci:get("nft-qos", "default", "static_rate_dl")
local def_rate_ul = uci:get("nft-qos", "default", "static_rate_ul")
local def_unit_dl = uci:get("nft-qos", "default", "static_unit_dl")
local def_unit_ul = uci:get("nft-qos", "default", "static_unit_ul")
local def_up = uci:get("nft-qos", "default", "dynamic_bw_up")
local def_down = uci:get("nft-qos", "default", "dynamic_bw_down")
local limit_enable = uci:get("nft-qos", "default", "limit_enable")
local limit_type = uci:get("nft-qos", "default", "limit_type")
local enable_priority = uci:get("nft-qos", "default", "priority_enable")
local has_ipv6 = fs.access("/proc/net/ipv6_route")
m = Map("nft-qos", translate("Qos over Nftables"))
--
-- Taboptions
--
s = m:section(TypedSection, "default", translate("NFT-QoS Settings"))
s.addremove = false
s.anonymous = true
s:tab("limit", "Limit Rate")
s:tab("priority", "Traffic Priority")
--
-- Static
--
o = s:taboption("limit", Flag, "limit_enable", translate("Limit Enable"), translate("Enable Limit Rate Feature"))
o.default = limit_enable or o.enabled
o.rmempty = false
o = s:taboption("limit", ListValue, "limit_type", translate("Limit Type"), translate("Type of Limit Rate"))
o.default = limit_static or "static"
o:depends("limit_enable","1")
o:value("static", "Static")
o:value("dynamic", "Dynamic")
o = s:taboption("limit", Value, "static_rate_dl", translate("Default Download Rate"), translate("Default value for download rate"))
o.datatype = "uinteger"
o.default = def_rate_dl or '50'
o:depends("limit_type","static")
o = s:taboption("limit", ListValue, "static_unit_dl", translate("Default Download Unit"), translate("Default unit for download rate"))
o.default = def_unit_dl or "kbytes"
o:depends("limit_type","static")
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
o = s:taboption("limit", Value, "static_rate_ul", translate("Default Upload Rate"), translate("Default value for upload rate"))
o.datatype = "uinteger"
o.default = def_rate_ul or '50'
o:depends("limit_type","static")
o = s:taboption("limit", ListValue, "static_unit_ul", translate("Default Upload Unit"), translate("Default unit for upload rate"))
o.default = def_unit_ul or "kbytes"
o:depends("limit_type","static")
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
--
-- Dynamic
--
o = s:taboption("limit", Value, "dynamic_bw_down", translate("Download Bandwidth (Mbps)"), translate("Default value for download bandwidth"))
o.default = def_up or '100'
o.datatype = "uinteger"
o:depends("limit_type","dynamic")
o = s:taboption("limit", Value, "dynamic_bw_up", translate("Upload Bandwidth (Mbps)"), translate("Default value for upload bandwidth"))
o.default = def_down or '100'
o.datatype = "uinteger"
o:depends("limit_type","dynamic")
o = s:taboption("limit", Value, "dynamic_cidr", translate("Target Network (IPv4/MASK)"), translate("Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc"))
o.datatype = "cidr4"
ipc.routes({ family = 4, type = 1 }, function(rt) o.default = rt.dest end)
o:depends("limit_type","dynamic")
if has_ipv6 then
o = s:taboption("limit", Value, "dynamic_cidr6", translate("Target Network6 (IPv6/MASK)"), translate("Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc"))
o.datatype = "cidr6"
o:depends("limit_type","dynamic")
end
o = s:taboption("limit", DynamicList, "limit_whitelist", translate("White List for Limit Rate"))
o.datatype = "ipaddr"
o:depends("limit_enable","1")
--
-- Priority
--
o = s:taboption("priority", Flag, "priority_enable", translate("Enable Traffic Priority"), translate("Enable this feature"))
o.default = enable_priority or o.enabled
o.rmempty = false
o = s:taboption("priority", ListValue, "priority_netdev", translate("Default Network Interface"), translate("Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc"))
o:depends("priority_enable", "1")
wa.cbi_add_networks(o)
--
-- Static Limit Rate - Download Rate
--
if limit_enable == "1" and limit_type == "static" then
x = m:section(TypedSection, "download", translate("Static QoS-Download Rate"))
x.anonymous = true
x.addremove = true
x.template = "cbi/tblsection"
o = x:option(Value, "hostname", translate("Hostname"))
o.datatype = "hostname"
o.default = 'undefined'
if has_ipv6 then
o = x:option(Value, "ipaddr", translate("IP Address(V4 / V6)"))
else
o = x:option(Value, "ipaddr", translate("IP Address(V4 Only)"))
end
o.datatype = "ipaddr"
if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then
o.titleref = luci.dispatcher.build_url("admin", "status", "overview")
end
o = x:option(Value, "macaddr", translate("MAC (optional)"))
o.rmempty = true
o.datatype = "macaddr"
o = x:option(Value, "rate", translate("Rate"))
o.default = def_rate_dl or '50'
o.size = 4
o.datatype = "uinteger"
o = x:option(ListValue, "unit", translate("Unit"))
o.default = def_unit_dl or "kbytes"
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
--
-- Static Limit Rate - Upload Rate
--
y = m:section(TypedSection, "upload", translate("Static QoS-Upload Rate"))
y.anonymous = true
y.addremove = true
y.template = "cbi/tblsection"
o = y:option(Value, "hostname", translate("Hostname"))
o.datatype = "hostname"
o.default = 'undefined'
if has_ipv6 then
o = y:option(Value, "ipaddr", translate("IP Address(V4 / V6)"))
else
o = y:option(Value, "ipaddr", translate("IP Address(V4 Only)"))
end
o.datatype = "ipaddr"
if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then
o.titleref = luci.dispatcher.build_url("admin", "status", "overview")
end
o = y:option(Value, "macaddr", translate("MAC (optional)"))
o.rmempty = true
o.datatype = "macaddr"
o = y:option(Value, "rate", translate("Rate"))
o.default = def_rate_ul or '50'
o.size = 4
o.datatype = "uinteger"
o = y:option(ListValue, "unit", translate("Unit"))
o.default = def_unit_ul or "kbytes"
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
end
--
-- Traffic Priority Settings
--
if enable_priority == "1" then
s = m:section(TypedSection, "priority", translate("Traffic Priority Settings"))
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"
o = s:option(ListValue, "protocol", translate("Protocol"))
o.default = "tcp"
o:value("tcp", "TCP")
o:value("udp", "UDP")
o:value("udplite", "UDP-Lite")
o:value("sctp", "SCTP")
o:value("dccp", "DCCP")
o = s:option(ListValue, "priority", translate("Priority"))
o.default = "1"
o:value("-400", "1")
o:value("-300", "2")
o:value("-225", "3")
o:value("-200", "4")
o:value("-150", "5")
o:value("-100", "6")
o:value("0", "7")
o:value("50", "8")
o:value("100", "9")
o:value("225", "10")
o:value("300", "11")
o = s:option(Value, "service", translate("Service"), translate("e.g. https, 23, (separator is comma)"))
o.default = '?'
o = s:option(Value, "comment", translate("Comment"))
o.default = '?'
end
return m

View file

@ -0,0 +1,167 @@
<%#
Copyright 2018 Rosy Song <rosysong@rosinson.com>
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<script type="text/javascript">//<![CDATA[
var bwxhr = new XHR();
var RC = { };
var em = 0;
var ec = 1;
var rate_table_dl;
var rate_table_ul;
function init_bytes(rl, ra) {
var bytes_pre;
var obj = { };
obj.chain = rl.chain;
obj.ipaddr = rl.expr[em].match.right;
obj.bytes = rl.expr[ec].counter.bytes;
obj.packets = rl.expr[ec].counter.packets;
obj.rate = 0;
if (RC[obj.chain] && RC[obj.chain][obj.ipaddr])
bytes_pre = RC[obj.chain][obj.ipaddr];
else
bytes_pre = 0;
obj.rate = (bytes_pre > 0) ? (obj.bytes - bytes_pre) / 3: 0;
if (!RC[obj.chain])
RC[obj.chain] = { };
RC[obj.chain][obj.ipaddr] = obj.bytes;
if (!ra[obj.chain])
ra[obj.chain] = [ ];
ra[obj.chain].push(obj);
} /* function init_bytes(rl, ra) */
function bytes_label(bytes) {
var uby = '<%:kB%>';
var kby = (bytes / 1024);
if (kby > 1024) {
uby = '<%:MB%>';
kby = (kby / 1024);
}
return String.format("%f %s", kby.toFixed(2), uby);
}
function print_table(tbl, rs, ra) {
ra.sort(function(a, b) { return b.rate - a.rate });
for (var i = 0; i < ra.length; i++) {
rs.push([
ra[i].ipaddr,
bytes_label(ra[i].rate) + '/s',
bytes_label(ra[i].bytes),
'%s Pkts.'.format(ra[i].packets),
]);
}
cbi_update_table(tbl, rs, '<em><%:No information available%></em>');
} /* function print_table(tbl, ra) */
/* wait for SVG */
window.setTimeout(
function() {
if (!RC)
{
window.setTimeout(arguments.callee, 1000);
}
else
{
rate_table_dl = document.getElementById('rate_table_dl');
rate_table_ul = document.getElementById('rate_table_ul');
/* render datasets, start update interval */
XHR.poll(3, '<%=build_url("admin/status/realtime/rate_status")%>', null,
function(x, json)
{
var RA = {};
var rows_dl = [];
var rows_ul = [];
var rules = json.nftables;
for (var i = 0; i < rules.length; i++)
{
if (!rules[i].rule)
continue;
if (rules[i].rule.table != 'nft-qos-monitor')
continue;
var rl = rules[i].rule;
switch (rl.chain)
{
case 'download':
case 'upload': init_bytes(rl, RA); break;
}
} /* for (var i = 0; i < rules.length; i++) */
/* display the result */
if (RA.download) {
while (rate_table_dl.firstElementChild !== rate_table_dl.lastElementChild)
rate_table_dl.removeChild(rate_table_dl.lastElementChild);
print_table(rate_table_dl, rows_dl, RA.download);
}
if (RA.upload) {
while (rate_table_ul.firstElementChild !== rate_table_ul.lastElementChild)
rate_table_ul.removeChild(rate_table_ul.lastElementChild);
print_table(rate_table_ul, rows_ul, RA.upload);
}
} /* function(x, json) */
); /* XHR.poll() */
XHR.run();
}
}, 1000
);
//]]></script>
<h2 name="content"><%:Realtime Rate%></h2>
<div class="cbi-map-descr"><%:This page gives an overview over currently download/upload rate.%></div>
<fieldset class="cbi-section" id="cbi-table-table">
<legend><%:Realtime Download Rate%></legend>
<div class="cbi-section-node">
<div class="table" id="rate_table_dl">
<div class="tr table-titles">
<div class="th col-2 hide-xs"><%:IP Address%></div>
<div class="th col-2"><%:Download Rate%></div>
<div class="th col-7"><%:Bytes Total%></div>
<div class="th col-7"><%:Packets Total%></div>
</div>
<div class="tr placeholder">
<div class="td">
<em><%:Collecting data...%></em>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset class="cbi-section" id="cbi-table-table">
<legend><%:Realtime Upload Rate%></legend>
<div class="cbi-section-node">
<div class="table" id="rate_table_ul">
<div class="tr table-titles">
<div class="th col-2 hide-xs"><%:IP Address%></div>
<div class="th col-2"><%:Upload Rate%></div>
<div class="th col-7"><%:Bytes Total%></div>
<div class="th col-7"><%:Packets Total%></div>
</div>
<div class="tr placeholder">
<div class="td">
<em><%:Collecting data...%></em>
</div>
</div>
</div>
</div>
</fieldset>
<%+footer%>

View file

@ -0,0 +1,161 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Bytes Total"
msgstr ""
msgid "Collecting data..."
msgstr ""
msgid "Comment"
msgstr ""
msgid "Default Download Rate"
msgstr ""
msgid "Default Download Unit"
msgstr ""
msgid "Default Network Interface"
msgstr ""
msgid "Default Upload Rate"
msgstr ""
msgid "Default Upload Unit"
msgstr ""
msgid "Default unit for download rate"
msgstr ""
msgid "Default unit for upload rate"
msgstr ""
msgid "Default value for download bandwidth"
msgstr ""
msgid "Default value for download rate"
msgstr ""
msgid "Default value for upload bandwidth"
msgstr ""
msgid "Default value for upload rate"
msgstr ""
msgid "Download Bandwidth (Mbps)"
msgstr ""
msgid "Download Rate"
msgstr ""
msgid "Dynamic Rate Limit"
msgstr ""
msgid "Enable Limit Rate Feature"
msgstr ""
msgid "Enable Traffic Priority"
msgstr ""
msgid "Enable this feature"
msgstr ""
msgid "Hostname"
msgstr ""
msgid "IP Address"
msgstr ""
msgid "Limit Enable"
msgstr ""
msgid "Limit Type"
msgstr ""
msgid "MAC (optional)"
msgstr ""
msgid "MB"
msgstr ""
msgid "NFT-QoS Settings"
msgstr ""
msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc"
msgstr ""
msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc"
msgstr ""
msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc"
msgstr ""
msgid "No information available"
msgstr ""
msgid "Packets Total"
msgstr ""
msgid "Priority"
msgstr ""
msgid "Protocol"
msgstr ""
msgid "Qos over Nftables"
msgstr ""
msgid "Rate"
msgstr ""
msgid "Rate Limit"
msgstr ""
msgid "Realtime Rate"
msgstr ""
msgid "Service"
msgstr ""
msgid "Static QoS-Download Rate"
msgstr ""
msgid "Static QoS-Upload Rate"
msgstr ""
msgid "Target Network (IPv4/MASK)"
msgstr ""
msgid "Target Network6 (IPv6/MASK)"
msgstr ""
msgid "This page gives an overview over currently download/upload rate."
msgstr ""
msgid "Traffic Priority"
msgstr ""
msgid "Traffic Priority Settings"
msgstr ""
msgid "Type of Limit Rate"
msgstr ""
msgid "Unit"
msgstr ""
msgid "Upload Bandwidth (Mbps)"
msgstr ""
msgid "Upload Rate"
msgstr ""
msgid "White List for Limit Rate"
msgstr ""
msgid "e.g. https, 23, (separator is comma)"
msgstr ""
msgid "kB"
msgstr ""

Binary file not shown.

View file

@ -0,0 +1,172 @@
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: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
"Language: zh_CN\n"
msgid "Bytes Total"
msgstr "字节总数"
msgid "Collecting data..."
msgstr "正在收集数据"
msgid "Comment"
msgstr "注释"
msgid "Default Download Rate"
msgstr "默认下载速率"
msgid "Default Download Unit"
msgstr "默认下载速率单位"
msgid "Default Network Interface"
msgstr "默认网络接口"
msgid "Default Upload Rate"
msgstr "默认上传速率"
msgid "Default Upload Unit"
msgstr "默认上传速率单位"
msgid "Default unit for download rate"
msgstr "默认的下载速率单位"
msgid "Default unit for upload rate"
msgstr "默认的上传速率单位"
msgid "Default value for download bandwidth"
msgstr "下载带宽的默认值"
msgid "Default value for download rate"
msgstr "下载速率的默认值"
msgid "Default value for upload bandwidth"
msgstr "上传带宽的默认值"
msgid "Default value for upload rate"
msgstr "上传速率的默认值"
msgid "Download Bandwidth (Mbps)"
msgstr "下载带宽 (Mbps)"
msgid "Download Rate"
msgstr "下载速率"
msgid "Dynamic Rate Limit"
msgstr "动态QoS"
msgid "Enable Limit Rate Feature"
msgstr "开启速率限制功能"
msgid "Enable Traffic Priority"
msgstr "开启流量优先级"
msgid "Enable this feature"
msgstr "开启这个功能"
msgid "Hostname"
msgstr "主机名"
msgid "IP Address"
msgstr "IP地址"
msgid "Limit Enable"
msgstr "限速开启"
msgid "Limit Type"
msgstr "限速类型"
msgid "MAC (optional)"
msgstr "物理地址(可选)"
msgid "MB"
msgstr "MB"
msgid "NFT-QoS Settings"
msgstr "NFT-QoS 设置"
msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc"
msgstr "流量整形的目标网络接口, 例如, br-lan, eth0.1, eth0, etc"
msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc"
msgstr "将要应用规则的网络, 例如, 192.168.1.0/24, 10.2.0.0/16, 等等"
msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc"
msgstr "将要应用规则的网络, 例如, AAAA::BBBB/64, CCCC::1/128, 等等"
msgid "No information available"
msgstr "没有更多的信息"
msgid "Packets Total"
msgstr "数据包总数"
msgid "Priority"
msgstr "优先级"
msgid "Protocol"
msgstr "协议"
msgid "Qos over Nftables"
msgstr "QoS Nftables版"
msgid "Rate"
msgstr "速率"
msgid "Rate Limit"
msgstr "速率限制"
msgid "Realtime Rate"
msgstr "实时速率显示"
msgid "Service"
msgstr "服务/端口"
msgid "Static QoS-Download Rate"
msgstr "静态QoS-下载速率"
msgid "Static QoS-Upload Rate"
msgstr "静态QoS-上传速率"
msgid "Target Network (IPv4/MASK)"
msgstr "目标网络(IPv4地址/掩码)"
msgid "Target Network6 (IPv6/MASK)"
msgstr "目标网络v6(IPv6地址/掩码)"
msgid "This page gives an overview over currently download/upload rate."
msgstr "该页面提供了当前上传和下载速率的一个总览"
msgid "Traffic Priority"
msgstr "流量优先级"
msgid "Traffic Priority Settings"
msgstr "流量优先级设置"
msgid "Type of Limit Rate"
msgstr "限速的类型"
msgid "Unit"
msgstr "单位"
msgid "Upload Bandwidth (Mbps)"
msgstr "上传带宽 (Mbps)"
msgid "Upload Rate"
msgstr "上传速率"
msgid "White List for Limit Rate"
msgstr "限速白名单"
msgid "e.g. https, 23, (separator is comma)"
msgstr "例如, https, 23 (用逗号分隔)"
msgid "kB"
msgstr "kB"

View file

@ -0,0 +1,172 @@
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.3\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
"Language: zh_CN\n"
msgid "Bytes Total"
msgstr "字节总数"
msgid "Collecting data..."
msgstr "正在收集数据"
msgid "Comment"
msgstr "注释"
msgid "Default Download Rate"
msgstr "默认下载速率"
msgid "Default Download Unit"
msgstr "默认下载速率单位"
msgid "Default Network Interface"
msgstr "默认网络接口"
msgid "Default Upload Rate"
msgstr "默认上传速率"
msgid "Default Upload Unit"
msgstr "默认上传速率单位"
msgid "Default unit for download rate"
msgstr "默认的下载速率单位"
msgid "Default unit for upload rate"
msgstr "默认的上传速率单位"
msgid "Default value for download bandwidth"
msgstr "下载带宽的默认值"
msgid "Default value for download rate"
msgstr "下载速率的默认值"
msgid "Default value for upload bandwidth"
msgstr "上传带宽的默认值"
msgid "Default value for upload rate"
msgstr "上传速率的默认值"
msgid "Download Bandwidth (Mbps)"
msgstr "下载带宽 (Mbps)"
msgid "Download Rate"
msgstr "下载速率"
msgid "Dynamic Rate Limit"
msgstr "动态QoS"
msgid "Enable Limit Rate Feature"
msgstr "开启速率限制功能"
msgid "Enable Traffic Priority"
msgstr "开启流量优先级"
msgid "Enable this feature"
msgstr "开启这个功能"
msgid "Hostname"
msgstr "主机名"
msgid "IP Address"
msgstr "IP地址"
msgid "Limit Enable"
msgstr "限速开启"
msgid "Limit Type"
msgstr "限速类型"
msgid "MAC (optional)"
msgstr "物理地址(可选)"
msgid "MB"
msgstr "MB"
msgid "NFT-QoS Settings"
msgstr "NFT-QoS 设置"
msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc"
msgstr "流量整形的目标网络接口, 例如, br-lan, eth0.1, eth0, etc"
msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc"
msgstr "将要应用规则的网络, 例如, 192.168.1.0/24, 10.2.0.0/16, 等等"
msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc"
msgstr "将要应用规则的网络, 例如, AAAA::BBBB/64, CCCC::1/128, 等等"
msgid "No information available"
msgstr "没有更多的信息"
msgid "Packets Total"
msgstr "数据包总数"
msgid "Priority"
msgstr "优先级"
msgid "Protocol"
msgstr "协议"
msgid "Qos over Nftables"
msgstr "QoS Nftables版"
msgid "Rate"
msgstr "速率"
msgid "Rate Limit"
msgstr "速率限制"
msgid "Realtime Rate"
msgstr "实时速率显示"
msgid "Service"
msgstr "服务/端口"
msgid "Static QoS-Download Rate"
msgstr "静态QoS-下载速率"
msgid "Static QoS-Upload Rate"
msgstr "静态QoS-上传速率"
msgid "Target Network (IPv4/MASK)"
msgstr "目标网络(IPv4地址/掩码)"
msgid "Target Network6 (IPv6/MASK)"
msgstr "目标网络v6(IPv6地址/掩码)"
msgid "This page gives an overview over currently download/upload rate."
msgstr "该页面提供了当前上传和下载速率的一个总览"
msgid "Traffic Priority"
msgstr "流量优先级"
msgid "Traffic Priority Settings"
msgstr "流量优先级设置"
msgid "Type of Limit Rate"
msgstr "限速的类型"
msgid "Unit"
msgstr "单位"
msgid "Upload Bandwidth (Mbps)"
msgstr "上传带宽 (Mbps)"
msgid "Upload Rate"
msgstr "上传速率"
msgid "White List for Limit Rate"
msgstr "限速白名单"
msgid "e.g. https, 23, (separator is comma)"
msgstr "例如, https, 23 (用逗号分隔)"
msgid "kB"
msgstr "kB"