luci-app-mwan3: fix assert if route could not select by ubus
[project/luci.git] / applications / luci-app-mwan3 / luasrc / controller / mwan3.lua
1 module("luci.controller.mwan3", package.seeall)
2
3 sys = require "luci.sys"
4 ut = require "luci.util"
5
6 ip = "ip -4 "
7
8 function index()
9 if not nixio.fs.access("/etc/config/mwan3") then
10 return
11 end
12
13 entry({"admin", "status", "mwan"},
14 alias("admin", "status", "mwan", "overview"),
15 _("Load Balancing"), 600)
16
17 entry({"admin", "status", "mwan", "overview"},
18 template("mwan/status_interface"))
19 entry({"admin", "status", "mwan", "detail"},
20 template("mwan/status_detail"))
21 entry({"admin", "status", "mwan", "diagnostics"},
22 template("mwan/status_diagnostics"))
23 entry({"admin", "status", "mwan", "troubleshooting"},
24 template("mwan/status_troubleshooting"))
25 entry({"admin", "status", "mwan", "interface_status"},
26 call("mwan_Status"))
27 entry({"admin", "status", "mwan", "detailed_status"},
28 call("detailedStatus"))
29 entry({"admin", "status", "mwan", "diagnostics_display"},
30 call("diagnosticsData"), nil).leaf = true
31 entry({"admin", "status", "mwan", "troubleshooting_display"},
32 call("troubleshootingData"))
33
34
35 entry({"admin", "network", "mwan"},
36 alias("admin", "network", "mwan", "interface"),
37 _("Load Balancing"), 600)
38
39 entry({"admin", "network", "mwan", "globals"},
40 cbi("mwan/globalsconfig"),
41 _("Globals"), 5).leaf = true
42 entry({"admin", "network", "mwan", "interface"},
43 arcombine(cbi("mwan/interface"), cbi("mwan/interfaceconfig")),
44 _("Interfaces"), 10).leaf = true
45 entry({"admin", "network", "mwan", "member"},
46 arcombine(cbi("mwan/member"), cbi("mwan/memberconfig")),
47 _("Members"), 20).leaf = true
48 entry({"admin", "network", "mwan", "policy"},
49 arcombine(cbi("mwan/policy"), cbi("mwan/policyconfig")),
50 _("Policies"), 30).leaf = true
51 entry({"admin", "network", "mwan", "rule"},
52 arcombine(cbi("mwan/rule"), cbi("mwan/ruleconfig")),
53 _("Rules"), 40).leaf = true
54 entry({"admin", "network", "mwan", "notify"},
55 cbi("mwan/notify"),
56 _("Notification"), 50).leaf = true
57 end
58
59 function mwan_Status()
60 local status = ut.ubus("mwan3", "status", {})
61
62 luci.http.prepare_content("application/json")
63 if status ~= nil then
64 luci.http.write_json(status)
65 else
66 luci.http.write_json({})
67 end
68 end
69
70 function detailedStatus()
71 local statusInfo = ut.trim(sys.exec("/usr/sbin/mwan3 status"))
72 luci.http.prepare_content("text/plain")
73 if statusInfo ~= "" then
74 luci.http.write(statusInfo)
75 else
76 luci.http.write("Unable to get status information")
77 end
78 end
79
80 function diagnosticsData(interface, task)
81 function getInterfaceNumber(interface)
82 local number = 0
83 local interfaceNumber
84 uci.cursor():foreach("mwan3", "interface",
85 function (section)
86 number = number+1
87 if section[".name"] == interface then
88 interfaceNumber = number
89 end
90 end
91 )
92 return interfaceNumber
93 end
94
95 function diag_command(cmd, addr)
96 if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
97 local util = io.popen(cmd % addr)
98 if util then
99 while true do
100 local ln = util:read("*l")
101 if not ln then break end
102 luci.http.write(ln)
103 luci.http.write("\n")
104 end
105 util:close()
106 end
107 return
108 end
109 end
110
111 function get_gateway(inteface)
112 local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
113 local gateway
114 if dump and dump.route then
115 local _, route
116 for _, route in ipairs(dump.route) do
117 if dump.route[_].target == "0.0.0.0" then
118 gateway = dump.route[_].nexthop
119 end
120 end
121 end
122 return gateway
123 end
124
125 local mArray = {}
126 local results = ""
127 local number = getInterfaceNumber(interface)
128
129 local uci = uci.cursor(nil, "/var/state")
130 local device = uci:get("network", interface, "ifname")
131
132 luci.http.prepare_content("text/plain")
133 if device ~= "" then
134 if task == "ping_gateway" then
135 local gateway = get_gateway(interface)
136 if gateway ~= nil then
137 diag_command("ping -c 5 -W 1 %q 2>&1", gateway)
138 else
139 luci.http.prepare_content("text/plain")
140 luci.http.write(string.format("No gateway for interface %s found.", interface))
141 end
142 elseif task == "ping_trackips" then
143 local trackips = uci:get("mwan3", interface, "track_ip")
144 if #trackips > 0 then
145 for i in pairs(trackips) do
146 diag_command("ping -c 5 -W 1 %q 2>&1", trackips[i])
147 end
148 else
149 luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
150 end
151 elseif task == "check_rules" then
152 local number = getInterfaceNumber(interface)
153 local iif = 1000 + number
154 local fwmark = 2000 + number
155 local iif_rule = sys.exec(string.format("ip rule | grep %d", iif))
156 local fwmark_rule = sys.exec(string.format("ip rule | grep %d", fwmark))
157 if iif_rule ~= "" and fwmark_rule ~= "" then
158 luci.http.write(string.format("All required IP rules for interface %s found", interface))
159 luci.http.write("\n")
160 luci.http.write(fwmark_rule)
161 luci.http.write(iif_rule)
162 elseif iif_rule == "" and fwmark_rule ~= "" then
163 luci.http.write(string.format("Only one IP rules for interface %s found", interface))
164 luci.http.write("\n")
165 luci.http.write(fwmark_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(iif_rule)
170 else
171 luci.http.write(string.format("Missing both IP rules for interface %s", interface))
172 end
173 elseif task == "check_routes" then
174 local number = getInterfaceNumber(interface)
175 local routeTable = sys.exec(string.format("ip route list table %s", number))
176 if routeTable ~= "" then
177 luci.http.write(string.format("Routing table %s for interface %s found", number, interface))
178 luci.http.write("\n")
179 luci.http.write(routeTable)
180 else
181 luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
182 end
183 elseif task == "hotplug_ifup" then
184 os.execute(string.format("/usr/sbin/mwan3 ifup %s", interface))
185 luci.http.write(string.format("Hotplug ifup sent to interface %s", interface))
186 elseif task == "hotplug_ifdown" then
187 os.execute(string.format("/usr/sbin/mwan3 ifdown %s", interface))
188 luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface))
189 else
190 luci.http.write("Unknown task")
191 end
192 else
193 luci.http.write(string.format("Unable to perform diagnostic tests on %s.", interface))
194 luci.http.write("\n")
195 luci.http.write("There is no physical or virtual device associated with this interface.")
196 end
197 end
198
199 function troubleshootingData()
200 local ver = require "luci.version"
201 local dash = "-------------------------------------------------"
202
203 luci.http.prepare_content("text/plain")
204
205 luci.http.write("\n")
206 luci.http.write("\n")
207 luci.http.write("Software-Version")
208 luci.http.write("\n")
209 luci.http.write(dash)
210 luci.http.write("\n")
211 if ver.distversion then
212 luci.http.write(string.format("OpenWrt - %s", ver.distversion))
213 luci.http.write("\n")
214 else
215 luci.http.write("OpenWrt - unknown")
216 luci.http.write("\n")
217 end
218
219 if ver.luciversion then
220 luci.http.write(string.format("LuCI - %s", ver.luciversion))
221 luci.http.write("\n")
222 else
223 luci.http.write("LuCI - unknown")
224 luci.http.write("\n")
225 end
226
227 luci.http.write("\n")
228 luci.http.write("\n")
229 local output = ut.trim(sys.exec("ip a show"))
230 luci.http.write("Output of \"ip a show\"")
231 luci.http.write("\n")
232 luci.http.write(dash)
233 luci.http.write("\n")
234 if output ~= "" then
235 luci.http.write(output)
236 luci.http.write("\n")
237 else
238 luci.http.write("No data found")
239 luci.http.write("\n")
240 end
241
242 luci.http.write("\n")
243 luci.http.write("\n")
244 local output = ut.trim(sys.exec("ip route show"))
245 luci.http.write("Output of \"ip route show\"")
246 luci.http.write("\n")
247 luci.http.write(dash)
248 luci.http.write("\n")
249 if output ~= "" then
250 luci.http.write(output)
251 luci.http.write("\n")
252 else
253 luci.http.write("No data found")
254 luci.http.write("\n")
255 end
256
257 luci.http.write("\n")
258 luci.http.write("\n")
259 local output = ut.trim(sys.exec("ip rule show"))
260 luci.http.write("Output of \"ip rule show\"")
261 luci.http.write("\n")
262 luci.http.write(dash)
263 luci.http.write("\n")
264 if output ~= "" then
265 luci.http.write(output)
266 luci.http.write("\n")
267 else
268 luci.http.write("No data found")
269 luci.http.write("\n")
270 end
271
272 luci.http.write("\n")
273 luci.http.write("\n")
274 luci.http.write("Output of \"ip route list table 1-250\"")
275 luci.http.write("\n")
276 luci.http.write(dash)
277 luci.http.write("\n")
278 for i=1,250 do
279 local output = ut.trim(sys.exec(string.format("ip route list table %d", i)))
280 if output ~= "" then
281 luci.http.write(string.format("Table %s: ", i))
282 luci.http.write(output)
283 luci.http.write("\n")
284 end
285 end
286
287 luci.http.write("\n")
288 luci.http.write("\n")
289 local output = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
290 luci.http.write("Output of \"iptables -L -t mangle -v -n\"")
291 luci.http.write("\n")
292 luci.http.write(dash)
293 luci.http.write("\n")
294 if output ~= "" then
295 luci.http.write(output)
296 luci.http.write("\n")
297 else
298 luci.http.write("No data found")
299 luci.http.write("\n")
300 end
301 end