luci-app-mwan3: fix legacy uci api usage
[project/luci.git] / applications / luci-app-mwan3 / luasrc / controller / mwan3.lua
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.
4
5 module("luci.controller.mwan3", package.seeall)
6
7 sys = require "luci.sys"
8 ut = require "luci.util"
9
10 ip = "ip -4 "
11
12 function index()
13 if not nixio.fs.access("/etc/config/mwan3") then
14 return
15 end
16
17 entry({"admin", "status", "mwan"},
18 alias("admin", "status", "mwan", "overview"),
19 _("Load Balancing"), 600)
20
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"},
30 call("mwan_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"))
37
38
39 entry({"admin", "network", "mwan"},
40 alias("admin", "network", "mwan", "interface"),
41 _("Load Balancing"), 600)
42
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"},
59 form("mwan/notify"),
60 _("Notification"), 50).leaf = true
61 end
62
63 function mwan_Status()
64 local status = ut.ubus("mwan3", "status", {})
65
66 luci.http.prepare_content("application/json")
67 if status ~= nil then
68 luci.http.write_json(status)
69 else
70 luci.http.write_json({})
71 end
72 end
73
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)
79 else
80 luci.http.write("Unable to get status information")
81 end
82 end
83
84 function diagnosticsData(interface, task)
85 function getInterfaceNumber(interface)
86 local number = 0
87 local interfaceNumber
88 uci.cursor():foreach("mwan3", "interface",
89 function (section)
90 number = number+1
91 if section[".name"] == interface then
92 interfaceNumber = number
93 end
94 end
95 )
96 return interfaceNumber
97 end
98
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))
102 if util then
103 while true do
104 local ln = util:read("*l")
105 if not ln then break end
106 luci.http.write(ln)
107 luci.http.write("\n")
108 end
109 util:close()
110 end
111 return
112 end
113 end
114
115 function get_gateway(inteface)
116 local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
117 local gateway
118 if dump and dump.route then
119 local _, route
120 for _, route in ipairs(dump.route) do
121 if dump.route[_].target == "0.0.0.0" then
122 gateway = dump.route[_].nexthop
123 end
124 end
125 end
126 return gateway
127 end
128
129 local mArray = {}
130 local results = ""
131 local number = getInterfaceNumber(interface)
132
133 local uci = uci.cursor(nil, "/var/state")
134 local device = uci:get("network", interface, "ifname")
135
136 luci.http.prepare_content("text/plain")
137 if device ~= "" then
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)
142 else
143 luci.http.prepare_content("text/plain")
144 luci.http.write(string.format("No gateway for interface %s found.", interface))
145 end
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])
151 end
152 else
153 luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
154 end
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)
174 else
175 luci.http.write(string.format("Missing both IP rules for interface %s", interface))
176 end
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)
184 else
185 luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
186 end
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))
193 else
194 luci.http.write("Unknown task")
195 end
196 else
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.")
200 end
201 end
202
203 function troubleshootingData()
204 local ver = require "luci.version"
205 local dash = "-------------------------------------------------"
206
207 luci.http.prepare_content("text/plain")
208
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")
218 else
219 luci.http.write("OpenWrt - unknown")
220 luci.http.write("\n")
221 end
222
223 if ver.luciversion then
224 luci.http.write(string.format("LuCI - %s", ver.luciversion))
225 luci.http.write("\n")
226 else
227 luci.http.write("LuCI - unknown")
228 luci.http.write("\n")
229 end
230
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")
238 if output ~= "" then
239 luci.http.write(output)
240 luci.http.write("\n")
241 else
242 luci.http.write("No data found")
243 luci.http.write("\n")
244 end
245
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")
253 if output ~= "" then
254 luci.http.write(output)
255 luci.http.write("\n")
256 else
257 luci.http.write("No data found")
258 luci.http.write("\n")
259 end
260
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")
268 if output ~= "" then
269 luci.http.write(output)
270 luci.http.write("\n")
271 else
272 luci.http.write("No data found")
273 luci.http.write("\n")
274 end
275
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")
282 for i=1,250 do
283 local output = ut.trim(sys.exec(string.format("ip route list table %d", i)))
284 if output ~= "" then
285 luci.http.write(string.format("Table %s: ", i))
286 luci.http.write(output)
287 luci.http.write("\n")
288 end
289 end
290
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")
298 if output ~= "" then
299 luci.http.write(output)
300 luci.http.write("\n")
301 else
302 luci.http.write("No data found")
303 luci.http.write("\n")
304 end
305 end