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 local uci = require "luci.model.uci".cursor()
89 uci:foreach("mwan3", "interface",
92 if section[".name"] == interface then
93 interfaceNumber = number
97 return interfaceNumber
100 function diag_command(cmd, addr)
101 if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
102 local util = io.popen(cmd % ut.shellquote(addr))
105 local ln = util:read("*l")
106 if not ln then break end
108 luci.http.write("\n")
116 function get_gateway(inteface)
117 local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
119 if dump and dump.route then
121 for _, route in ipairs(dump.route) do
122 if dump.route[_].target == "0.0.0.0" then
123 gateway = dump.route[_].nexthop
132 local number = getInterfaceNumber(interface)
134 local uci = require "luci.model.uci".cursor(nil, "/var/state")
135 local device = uci:get("network", interface, "ifname")
137 luci.http.prepare_content("text/plain")
139 if task == "ping_gateway" then
140 local gateway = get_gateway(interface)
141 if gateway ~= nil then
142 diag_command("ping -c 5 -W 1 %s 2>&1", gateway)
144 luci.http.prepare_content("text/plain")
145 luci.http.write(string.format("No gateway for interface %s found.", interface))
147 elseif task == "ping_trackips" then
148 local trackips = uci:get("mwan3", interface, "track_ip")
149 if #trackips > 0 then
150 for i in pairs(trackips) do
151 diag_command("ping -c 5 -W 1 %s 2>&1", trackips[i])
154 luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
156 elseif task == "check_rules" then
157 local number = getInterfaceNumber(interface)
158 local iif = 1000 + number
159 local fwmark = 2000 + number
160 local iif_rule = sys.exec(string.format("ip rule | grep %d", iif))
161 local fwmark_rule = sys.exec(string.format("ip rule | grep %d", fwmark))
162 if iif_rule ~= "" and fwmark_rule ~= "" then
163 luci.http.write(string.format("All required IP rules for interface %s found", interface))
164 luci.http.write("\n")
165 luci.http.write(fwmark_rule)
166 luci.http.write(iif_rule)
167 elseif iif_rule == "" and fwmark_rule ~= "" then
168 luci.http.write(string.format("Only one IP rules for interface %s found", interface))
169 luci.http.write("\n")
170 luci.http.write(fwmark_rule)
171 elseif iif_rule ~= "" and fwmark_rule == "" then
172 luci.http.write(string.format("Only one IP rules for interface %s found", interface))
173 luci.http.write("\n")
174 luci.http.write(iif_rule)
176 luci.http.write(string.format("Missing both IP rules for interface %s", interface))
178 elseif task == "check_routes" then
179 local number = getInterfaceNumber(interface)
180 local routeTable = sys.exec(string.format("ip route list table %s", number))
181 if routeTable ~= "" then
182 luci.http.write(string.format("Routing table %s for interface %s found", number, interface))
183 luci.http.write("\n")
184 luci.http.write(routeTable)
186 luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
188 elseif task == "hotplug_ifup" then
189 os.execute(string.format("/usr/sbin/mwan3 ifup %s", ut.shellquote(interface)))
190 luci.http.write(string.format("Hotplug ifup sent to interface %s", interface))
191 elseif task == "hotplug_ifdown" then
192 os.execute(string.format("/usr/sbin/mwan3 ifdown %s", ut.shellquote(interface)))
193 luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface))
195 luci.http.write("Unknown task")
198 luci.http.write(string.format("Unable to perform diagnostic tests on %s.", interface))
199 luci.http.write("\n")
200 luci.http.write("There is no physical or virtual device associated with this interface.")
204 function troubleshootingData()
205 local ver = require "luci.version"
206 local dash = "-------------------------------------------------"
208 luci.http.prepare_content("text/plain")
210 luci.http.write("\n")
211 luci.http.write("\n")
212 luci.http.write("Software-Version")
213 luci.http.write("\n")
214 luci.http.write(dash)
215 luci.http.write("\n")
216 if ver.distversion then
217 luci.http.write(string.format("OpenWrt - %s", ver.distversion))
218 luci.http.write("\n")
220 luci.http.write("OpenWrt - unknown")
221 luci.http.write("\n")
224 if ver.luciversion then
225 luci.http.write(string.format("LuCI - %s", ver.luciversion))
226 luci.http.write("\n")
228 luci.http.write("LuCI - unknown")
229 luci.http.write("\n")
232 luci.http.write("\n")
233 luci.http.write("\n")
234 local output = ut.trim(sys.exec("ip a show"))
235 luci.http.write("Output of \"ip a show\"")
236 luci.http.write("\n")
237 luci.http.write(dash)
238 luci.http.write("\n")
240 luci.http.write(output)
241 luci.http.write("\n")
243 luci.http.write("No data found")
244 luci.http.write("\n")
247 luci.http.write("\n")
248 luci.http.write("\n")
249 local output = ut.trim(sys.exec("ip route show"))
250 luci.http.write("Output of \"ip route show\"")
251 luci.http.write("\n")
252 luci.http.write(dash)
253 luci.http.write("\n")
255 luci.http.write(output)
256 luci.http.write("\n")
258 luci.http.write("No data found")
259 luci.http.write("\n")
262 luci.http.write("\n")
263 luci.http.write("\n")
264 local output = ut.trim(sys.exec("ip rule show"))
265 luci.http.write("Output of \"ip rule show\"")
266 luci.http.write("\n")
267 luci.http.write(dash)
268 luci.http.write("\n")
270 luci.http.write(output)
271 luci.http.write("\n")
273 luci.http.write("No data found")
274 luci.http.write("\n")
277 luci.http.write("\n")
278 luci.http.write("\n")
279 luci.http.write("Output of \"ip route list table 1-250\"")
280 luci.http.write("\n")
281 luci.http.write(dash)
282 luci.http.write("\n")
284 local output = ut.trim(sys.exec(string.format("ip route list table %d", i)))
286 luci.http.write(string.format("Table %s: ", i))
287 luci.http.write(output)
288 luci.http.write("\n")
292 luci.http.write("\n")
293 luci.http.write("\n")
294 local output = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
295 luci.http.write("Output of \"iptables -L -t mangle -v -n\"")
296 luci.http.write("\n")
297 luci.http.write(dash)
298 luci.http.write("\n")
300 luci.http.write(output)
301 luci.http.write("\n")
303 luci.http.write("No data found")
304 luci.http.write("\n")