You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
8.0 KiB

  1. --[[
  2. LuCI - Lua Configuration Interface
  3. Copyright 2014 Steven Barth <steven@midlink.org>
  4. Copyright 2014 Dave Taht <dave.taht@bufferbloat.net>
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. $Id$
  10. ]]--
  11. local wa = require "luci.tools.webadmin"
  12. local fs = require "nixio.fs"
  13. local net = require "luci.model.network".init()
  14. local sys = require "luci.sys"
  15. --local ifaces = net:get_interfaces()
  16. local ifaces = sys.net:devices()
  17. local path = "/usr/lib/sqm"
  18. m = Map("sqm", translate("Smart Queue Management"),
  19. translate("With <abbr title=\"Smart Queue Management\">SQM</abbr> you " ..
  20. "can enable traffic shaping, better mixing (Fair Queueing)," ..
  21. " active queue length management (AQM) " ..
  22. " and prioritisation on one " ..
  23. "network interface."))
  24. s = m:section(TypedSection, "queue", translate("Queues"))
  25. s:tab("tab_basic", translate("Basic Settings"))
  26. s:tab("tab_qdisc", translate("Queue Discipline"))
  27. s:tab("tab_linklayer", translate("Link Layer Adaptation"))
  28. s.addremove = true -- set to true to allow adding SQM instances in the GUI
  29. s.anonymous = true
  30. -- BASIC
  31. e = s:taboption("tab_basic", Flag, "enabled", translate("Enable"))
  32. e.rmempty = false
  33. n = s:taboption("tab_basic", ListValue, "interface", translate("Interface name"))
  34. -- sm lifted from luci-app-wol, the original implementation failed to show pppoe-ge00 type interface names
  35. for _, iface in ipairs(ifaces) do
  36. -- if iface:is_up() then
  37. -- n:value(iface:name())
  38. -- end
  39. if iface ~= "lo" then
  40. n:value(iface)
  41. end
  42. end
  43. n.rmempty = false
  44. dl = s:taboption("tab_basic", Value, "download", translate("Download speed (kbit/s) (ingress) set to 0 to selectively disable ingress shaping:"))
  45. dl.datatype = "and(uinteger,min(0))"
  46. dl.rmempty = false
  47. ul = s:taboption("tab_basic", Value, "upload", translate("Upload speed (kbit/s) (egress) set to 0 to selectively disable egress shaping:"))
  48. ul.datatype = "and(uinteger,min(0))"
  49. ul.rmempty = false
  50. -- QDISC
  51. c = s:taboption("tab_qdisc", ListValue, "qdisc", translate("Queueing discipline"))
  52. c:value("fq_codel", "fq_codel ("..translate("default")..")")
  53. c:value("efq_codel")
  54. c:value("nfq_codel")
  55. c:value("sfq")
  56. c:value("codel")
  57. c:value("ns2_codel")
  58. c:value("pie")
  59. c:value("sfq")
  60. c.default = "fq_codel"
  61. c.rmempty = false
  62. local qos_desc = ""
  63. sc = s:taboption("tab_qdisc", ListValue, "script", translate("Queue setup script"))
  64. for file in fs.dir(path) do
  65. if string.find(file, ".qos$") then
  66. sc:value(file)
  67. end
  68. if string.find(file, ".qos.help$") then
  69. fh = io.open(path .. "/" .. file, "r")
  70. qos_desc = qos_desc .. "<p><b>" .. file:gsub(".help$", "") .. ":</b><br />" .. fh:read("*a") .. "</p>"
  71. end
  72. end
  73. sc.default = "simple.qos"
  74. sc.rmempty = false
  75. sc.description = qos_desc
  76. ad = s:taboption("tab_qdisc", Flag, "qdisc_advanced", translate("Show and Use Advanced Configuration"))
  77. ad.default = false
  78. ad.rmempty = true
  79. squash_dscp = s:taboption("tab_qdisc", ListValue, "squash_dscp", translate("Squash DSCP on inbound packets (ingress):"))
  80. squash_dscp:value("1", "SQUASH")
  81. squash_dscp:value("0", "DO NOT SQUASH")
  82. squash_dscp.default = "1"
  83. squash_dscp.rmempty = true
  84. squash_dscp:depends("qdisc_advanced", "1")
  85. squash_ingress = s:taboption("tab_qdisc", ListValue, "squash_ingress", translate("Ignore DSCP on ingress:"))
  86. squash_ingress:value("1", "Ignore")
  87. squash_ingress:value("0", "Allow")
  88. squash_ingress.default = "1"
  89. squash_ingress.rmempty = true
  90. squash_ingress:depends("qdisc_advanced", "1")
  91. iecn = s:taboption("tab_qdisc", ListValue, "ingress_ecn", translate("Explicit congestion notification (ECN) status on inbound packets (ingress):"))
  92. iecn:value("ECN", "ECN ("..translate("default")..")")
  93. iecn:value("NOECN")
  94. iecn.default = "ECN"
  95. iecn.rmempty = true
  96. iecn:depends("qdisc_advanced", "1")
  97. eecn = s:taboption("tab_qdisc", ListValue, "egress_ecn", translate("Explicit congestion notification (ECN) status on outbound packets (egress)."))
  98. eecn:value("NOECN", "NOECN ("..translate("default")..")")
  99. eecn:value("ECN")
  100. eecn.default = "NOECN"
  101. eecn.rmempty = true
  102. eecn:depends("qdisc_advanced", "1")
  103. ad2 = s:taboption("tab_qdisc", Flag, "qdisc_really_really_advanced", translate("Show and Use Dangerous Configuration"))
  104. ad2.default = false
  105. ad2.rmempty = true
  106. ad2:depends("qdisc_advanced", "1")
  107. ilim = s:taboption("tab_qdisc", Value, "ilimit", translate("Hard limit on ingress queues; leave empty for default."))
  108. -- ilim.default = 1000
  109. ilim.isnumber = true
  110. ilim.datatype = "and(uinteger,min(0))"
  111. ilim.rmempty = true
  112. ilim:depends("qdisc_really_really_advanced", "1")
  113. elim = s:taboption("tab_qdisc", Value, "elimit", translate("Hard limit on egress queues; leave empty for default."))
  114. -- elim.default = 1000
  115. elim.datatype = "and(uinteger,min(0))"
  116. elim.rmempty = true
  117. elim:depends("qdisc_really_really_advanced", "1")
  118. itarg = s:taboption("tab_qdisc", Value, "itarget", translate("Latency target for ingress, e.g 5ms [units: s, ms, or us]; leave empty for automatic selection, put in the word default for the qdisc's default."))
  119. itarg.datatype = "string"
  120. itarg.rmempty = true
  121. itarg:depends("qdisc_really_really_advanced", "1")
  122. etarg = s:taboption("tab_qdisc", Value, "etarget", translate("Latency target for egress, e.g. 5ms [units: s, ms, or us]; leave empty for automatic selection, put in the word default for the qdisc's default."))
  123. etarg.datatype = "string"
  124. etarg.rmempty = true
  125. etarg:depends("qdisc_really_really_advanced", "1")
  126. iqdisc_opts = s:taboption("tab_qdisc", Value, "iqdisc_opts", translate("Advanced option string to pass to the ingress queueing disciplines; no error checking, use very carefully."))
  127. iqdisc_opts.rmempty = true
  128. iqdisc_opts:depends("qdisc_really_really_advanced", "1")
  129. eqdisc_opts = s:taboption("tab_qdisc", Value, "eqdisc_opts", translate("Advanced option string to pass to the egress queueing disciplines; no error checking, use very carefully."))
  130. eqdisc_opts.rmempty = true
  131. eqdisc_opts:depends("qdisc_really_really_advanced", "1")
  132. -- LINKLAYER
  133. ll = s:taboption("tab_linklayer", ListValue, "linklayer", translate("Which link layer to account for:"))
  134. ll:value("none", "none ("..translate("default")..")")
  135. ll:value("ethernet", "Ethernet with overhead: select for e.g. VDSL2.")
  136. ll:value("atm", "ATM: select for e.g. ADSL1, ADSL2, ADSL2+.")
  137. -- ll:value("adsl") -- reduce the options
  138. ll.default = "none"
  139. po = s:taboption("tab_linklayer", Value, "overhead", translate("Per Packet Overhead (byte):"))
  140. po.datatype = "and(integer,min(-1500))"
  141. po.default = 0
  142. po.isnumber = true
  143. po.rmempty = true
  144. po:depends("linklayer", "ethernet")
  145. -- po:depends("linklayer", "adsl")
  146. po:depends("linklayer", "atm")
  147. adll = s:taboption("tab_linklayer", Flag, "linklayer_advanced", translate("Show Advanced Linklayer Options, (only needed if MTU > 1500)"))
  148. adll.rmempty = true
  149. adll:depends("linklayer", "ethernet")
  150. -- adll:depends("linklayer", "adsl")
  151. adll:depends("linklayer", "atm")
  152. smtu = s:taboption("tab_linklayer", Value, "tcMTU", translate("Maximal Size for size and rate calculations, tcMTU (byte); needs to be >= interface MTU + overhead:"))
  153. smtu.datatype = "and(uinteger,min(0))"
  154. smtu.default = 2047
  155. smtu.isnumber = true
  156. smtu.rmempty = true
  157. smtu:depends("linklayer_advanced", "1")
  158. stsize = s:taboption("tab_linklayer", Value, "tcTSIZE", translate("Number of entries in size/rate tables, TSIZE; for ATM choose TSIZE = (tcMTU + 1) / 16:"))
  159. stsize.datatype = "and(uinteger,min(0))"
  160. stsize.default = 128
  161. stsize.isnumber = true
  162. stsize.rmempty = true
  163. stsize:depends("linklayer_advanced", "1")
  164. smpu = s:taboption("tab_linklayer", Value, "tcMPU", translate("Minimal packet size, MPU (byte); needs to be > 0 for ethernet size tables:"))
  165. smpu.datatype = "and(uinteger,min(0))"
  166. smpu.default = 0
  167. smpu.isnumber = true
  168. smpu.rmempty = true
  169. smpu:depends("linklayer_advanced", "1")
  170. lla = s:taboption("tab_linklayer", ListValue, "linklayer_adaptation_mechanism", translate("Which linklayer adaptation mechanism to use; for testing only"))
  171. lla:value("htb_private")
  172. lla:value("tc_stab", "tc_stab ("..translate("default")..")")
  173. lla.default = "tc_stab"
  174. lla.rmempty = true
  175. lla:depends("linklayer_advanced", "1")
  176. -- PRORITIES?
  177. return m