1 -- Copyright 2014 Aedan Renner <chipdankly@gmail.com>
2 -- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
3 -- Licensed to the public under the GNU General Public License v2.
5 module("luci.controller.mwan3", package.seeall)
7 sys = require "luci.sys"
8 ut = require "luci.util"
13 if not nixio.fs.access("/etc/config/mwan3") then
17 entry({"admin", "status", "mwan"},
18 alias("admin", "status", "mwan", "overview"),
19 _("Load Balancing"), 600)
21 entry({"admin", "status", "mwan", "overview"},
22 template("mwan/status_interface"))
23 entry({"admin", "status", "mwan", "detail"},
24 template("mwan/status_detail"))
25 entry({"admin", "status", "mwan", "diagnostics"},
26 template("mwan/status_diagnostics"))
27 entry({"admin", "status", "mwan", "troubleshooting"},
28 template("mwan/status_troubleshooting"))
29 entry({"admin", "status", "mwan", "interface_status"},
31 entry({"admin", "status", "mwan", "detailed_status"},
32 call("detailedStatus"))
33 entry({"admin", "status", "mwan", "diagnostics_display"},
34 call("diagnosticsData"), nil).leaf = true
35 entry({"admin", "status", "mwan", "troubleshooting_display"},
36 call("troubleshootingData"))
39 entry({"admin", "network", "mwan"},
40 alias("admin", "network", "mwan", "interface"),
41 _("Load Balancing"), 600)
43 entry({"admin", "network", "mwan", "globals"},
44 cbi("mwan/globalsconfig"),
45 _("Globals"), 5).leaf = true
46 entry({"admin", "network", "mwan", "interface"},
47 arcombine(cbi("mwan/interface"), cbi("mwan/interfaceconfig")),
48 _("Interfaces"), 10).leaf = true
49 entry({"admin", "network", "mwan", "member"},
50 arcombine(cbi("mwan/member"), cbi("mwan/memberconfig")),
51 _("Members"), 20).leaf = true
52 entry({"admin", "network", "mwan", "policy"},
53 arcombine(cbi("mwan/policy"), cbi("mwan/policyconfig")),
54 _("Policies"), 30).leaf = true
55 entry({"admin", "network", "mwan", "rule"},
56 arcombine(cbi("mwan/rule"), cbi("mwan/ruleconfig")),
57 _("Rules"), 40).leaf = true
58 entry({"admin", "network", "mwan", "notify"},
60 _("Notification"), 50).leaf = true
63 function mwan_Status()
64 local status = ut.ubus("mwan3", "status", {})
66 luci.http.prepare_content("application/json")
68 luci.http.write_json(status)
70 luci.http.write_json({})
74 function detailedStatus()
75 local statusInfo = ut.trim(sys.exec("/usr/sbin/mwan3 status"))
76 luci.http.prepare_content("text/plain")
77 if statusInfo ~= "" then
78 luci.http.write(statusInfo)
80 luci.http.write("Unable to get status information")
84 function diagnosticsData(interface, task)
85 function getInterfaceNumber(interface)
88 uci.cursor():foreach("mwan3", "interface",
91 if section[".name"] == interface then
92 interfaceNumber = number
96 return interfaceNumber
99 function diag_command(cmd, addr)
100 if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
101 local util = io.popen(cmd % ut.shellquote(addr))
104 local ln = util:read("*l")
105 if not ln then break end
107 luci.http.write("\n")
115 function get_gateway(inteface)
116 local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
118 if dump and dump.route then
120 for _, route in ipairs(dump.route) do
121 if dump.route[_].target == "0.0.0.0" then
122 gateway = dump.route[_].nexthop
131 local number = getInterfaceNumber(interface)
133 local uci = uci.cursor(nil, "/var/state")
134 local device = uci:get("network", interface, "ifname")
136 luci.http.prepare_content("text/plain")
138 if task == "ping_gateway" then
139 local gateway = get_gateway(interface)
140 if gateway ~= nil then
141 diag_command("ping -c 5 -W 1 %s 2>&1", gateway)
143 luci.http.prepare_content("text/plain")
144 luci.http.write(string.format("No gateway for interface %s found.", interface))
146 elseif task == "ping_trackips" then
147 local trackips = uci:get("mwan3", interface, "track_ip")
148 if #trackips > 0 then
149 for i in pairs(trackips) do
150 diag_command("ping -c 5 -W 1 %s 2>&1", trackips[i])
153 luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
155 elseif task == "check_rules" then
156 local number = getInterfaceNumber(interface)
157 local iif = 1000 + number
158 local fwmark = 2000 + number
159 local iif_rule = sys.exec(string.format("ip rule | grep %d", iif))
160 local fwmark_rule = sys.exec(string.format("ip rule | grep %d", fwmark))
161 if iif_rule ~= "" and fwmark_rule ~= "" then
162 luci.http.write(string.format("All required IP rules for interface %s found", interface))
163 luci.http.write("\n")
164 luci.http.write(fwmark_rule)
165 luci.http.write(iif_rule)
166 elseif iif_rule == "" and fwmark_rule ~= "" then
167 luci.http.write(string.format("Only one IP rules for interface %s found", interface))
168 luci.http.write("\n")
169 luci.http.write(fwmark_rule)
170 elseif iif_rule ~= "" and fwmark_rule == "" then
171 luci.http.write(string.format("Only one IP rules for interface %s found", interface))
172 luci.http.write("\n")
173 luci.http.write(iif_rule)
175 luci.http.write(string.format("Missing both IP rules for interface %s", interface))
177 elseif task == "check_routes" then
178 local number = getInterfaceNumber(interface)
179 local routeTable = sys.exec(string.format("ip route list table %s", number))
180 if routeTable ~= "" then
181 luci.http.write(string.format("Routing table %s for interface %s found", number, interface))
182 luci.http.write("\n")
183 luci.http.write(routeTable)
185 luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
187 elseif task == "hotplug_ifup" then
188 os.execute(string.format("/usr/sbin/mwan3 ifup %s", ut.shellquote(interface)))
189 luci.http.write(string.format("Hotplug ifup sent to interface %s", interface))
190 elseif task == "hotplug_ifdown" then
191 os.execute(string.format("/usr/sbin/mwan3 ifdown %s", ut.shellquote(interface)))
192 luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface))
194 luci.http.write("Unknown task")
197 luci.http.write(string.format("Unable to perform diagnostic tests on %s.", interface))
198 luci.http.write("\n")
199 luci.http.write("There is no physical or virtual device associated with this interface.")
203 function troubleshootingData()
204 local ver = require "luci.version"
205 local dash = "-------------------------------------------------"
207 luci.http.prepare_content("text/plain")
209 luci.http.write("\n")
210 luci.http.write("\n")
211 luci.http.write("Software-Version")
212 luci.http.write("\n")
213 luci.http.write(dash)
214 luci.http.write("\n")
215 if ver.distversion then
216 luci.http.write(string.format("OpenWrt - %s", ver.distversion))
217 luci.http.write("\n")
219 luci.http.write("OpenWrt - unknown")
220 luci.http.write("\n")
223 if ver.luciversion then
224 luci.http.write(string.format("LuCI - %s", ver.luciversion))
225 luci.http.write("\n")
227 luci.http.write("LuCI - unknown")
228 luci.http.write("\n")
231 luci.http.write("\n")
232 luci.http.write("\n")
233 local output = ut.trim(sys.exec("ip a show"))
234 luci.http.write("Output of \"ip a show\"")
235 luci.http.write("\n")
236 luci.http.write(dash)
237 luci.http.write("\n")
239 luci.http.write(output)
240 luci.http.write("\n")
242 luci.http.write("No data found")
243 luci.http.write("\n")
246 luci.http.write("\n")
247 luci.http.write("\n")
248 local output = ut.trim(sys.exec("ip route show"))
249 luci.http.write("Output of \"ip route show\"")
250 luci.http.write("\n")
251 luci.http.write(dash)
252 luci.http.write("\n")
254 luci.http.write(output)
255 luci.http.write("\n")
257 luci.http.write("No data found")
258 luci.http.write("\n")
261 luci.http.write("\n")
262 luci.http.write("\n")
263 local output = ut.trim(sys.exec("ip rule show"))
264 luci.http.write("Output of \"ip rule show\"")
265 luci.http.write("\n")
266 luci.http.write(dash)
267 luci.http.write("\n")
269 luci.http.write(output)
270 luci.http.write("\n")
272 luci.http.write("No data found")
273 luci.http.write("\n")
276 luci.http.write("\n")
277 luci.http.write("\n")
278 luci.http.write("Output of \"ip route list table 1-250\"")
279 luci.http.write("\n")
280 luci.http.write(dash)
281 luci.http.write("\n")
283 local output = ut.trim(sys.exec(string.format("ip route list table %d", i)))
285 luci.http.write(string.format("Table %s: ", i))
286 luci.http.write(output)
287 luci.http.write("\n")
291 luci.http.write("\n")
292 luci.http.write("\n")
293 local output = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
294 luci.http.write("Output of \"iptables -L -t mangle -v -n\"")
295 luci.http.write("\n")
296 luci.http.write(dash)
297 luci.http.write("\n")
299 luci.http.write(output)
300 luci.http.write("\n")
302 luci.http.write("No data found")
303 luci.http.write("\n")