1 module("luci.controller.mwan3", package.seeall)
3 sys = require "luci.sys"
4 ut = require "luci.util"
9 if not nixio.fs.access("/etc/config/mwan3") then
13 entry({"admin", "status", "mwan"},
14 alias("admin", "status", "mwan", "overview"),
15 _("Load Balancing"), 600)
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"},
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"))
35 entry({"admin", "network", "mwan"},
36 alias("admin", "network", "mwan", "interface"),
37 _("Load Balancing"), 600)
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"},
56 _("Notification"), 50).leaf = true
59 function mwan_Status()
60 local status = ut.ubus("mwan3", "status", {})
62 luci.http.prepare_content("application/json")
64 luci.http.write_json(status)
66 luci.http.write_json({})
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)
76 luci.http.write("Unable to get status information")
80 function diagnosticsData(interface, task)
81 function getInterfaceNumber(interface)
84 uci.cursor():foreach("mwan3", "interface",
87 if section[".name"] == interface then
88 interfaceNumber = number
92 return interfaceNumber
95 function diag_command(cmd, addr)
96 if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
97 local util = io.popen(cmd % addr)
100 local ln = util:read("*l")
101 if not ln then break end
103 luci.http.write("\n")
111 function get_gateway(inteface)
112 local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
116 for _, route in ipairs(dump.route) do
117 if dump.route[_].target == "0.0.0.0" then
118 gateway = dump.route[_].nexthop
127 local number = getInterfaceNumber(interface)
129 local uci = uci.cursor(nil, "/var/state")
130 local device = uci:get("network", interface, "ifname")
132 luci.http.prepare_content("text/plain")
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)
139 luci.http.prepare_content("text/plain")
140 luci.http.write(string.format("No gateway for interface %s found.", interface))
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])
149 luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
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)
171 luci.http.write(string.format("Missing both IP rules for interface %s", interface))
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)
181 luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
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))
190 luci.http.write("Unknown task")
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.")
199 function troubleshootingData()
200 local ver = require "luci.version"
205 local wrtRelease = ut.trim(ver.distversion)
206 if wrtRelease ~= "" then
207 wrtRelease = "OpenWrt - " .. wrtRelease
209 wrtRelease = "OpenWrt - unknown"
211 local luciRelease = ut.trim(ver.luciversion)
212 if luciRelease ~= "" then
213 luciRelease = "\nLuCI - " .. luciRelease
215 luciRelease = "\nLuCI - unknown"
217 local mwanVersion = ut.trim(sys.exec("opkg info mwan3 | grep Version | awk '{print $2}'"))
218 if mwanVersion ~= "" then
219 mwanVersion = "\n\nmwan3 - " .. mwanVersion
221 mwanVersion = "\n\nmwan3 - unknown"
223 local mwanLuciVersion = ut.trim(sys.exec("opkg info luci-app-mwan3 | grep Version | awk '{print $2}'"))
224 if mwanLuciVersion ~= "" then
225 mwanLuciVersion = "\nmwan3-luci - " .. mwanLuciVersion
227 mwanLuciVersion = "\nmwan3-luci - unknown"
229 mArray.versions = { wrtRelease .. luciRelease .. mwanVersion .. mwanLuciVersion }
232 local mwanConfig = ut.trim(sys.exec("cat /etc/config/mwan3"))
233 if mwanConfig == "" then
234 mwanConfig = "No data found"
236 mArray.mwanconfig = { mwanConfig }
239 local networkConfig = ut.trim(sys.exec("cat /etc/config/network | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/'"))
240 if networkConfig == "" then
241 networkConfig = "No data found"
243 mArray.netconfig = { networkConfig }
246 local wirelessConfig = ut.trim(sys.exec("cat /etc/config/wireless | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/' -e 's/.*key.*/ KEY HIDDEN/'"))
247 if wirelessConfig == "" then
248 wirelessConfig = "No data found"
250 mArray.wificonfig = { wirelessConfig }
253 local ifconfig = ut.trim(sys.exec("ifconfig"))
254 if ifconfig == "" then
255 ifconfig = "No data found"
257 mArray.ifconfig = { ifconfig }
260 local routeShow = ut.trim(sys.exec("route -n"))
261 if routeShow == "" then
262 routeShow = "No data found"
264 mArray.routeshow = { routeShow }
267 local ipRuleShow = ut.trim(sys.exec(ip .. "rule show"))
268 if ipRuleShow == "" then
269 ipRuleShow = "No data found"
271 mArray.iprule = { ipRuleShow }
273 -- ip route list table 1-250
274 local routeList, routeString = ut.trim(sys.exec(ip .. "rule | sed 's/://g' 2>/dev/null | awk '$1>=2001 && $1<=2250' | awk '{print $NF}'")), ""
275 if routeList ~= "" then
276 for line in routeList:gmatch("[^\r\n]+") do
277 routeString = routeString .. line .. "\n" .. sys.exec(ip .. "route list table " .. line)
279 routeString = ut.trim(routeString)
281 routeString = "No data found"
283 mArray.routelist = { routeString }
285 -- default firewall output policy
286 local firewallOut = ut.trim(sys.exec("uci -q -p /var/state get firewall.@defaults[0].output"))
287 if firewallOut == "" then
288 firewallOut = "No data found"
290 mArray.firewallout = { firewallOut }
293 local iptables = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
294 if iptables == "" then
295 iptables = "No data found"
297 mArray.iptables = { iptables }
299 luci.http.prepare_content("application/json")
300 luci.http.write_json(mArray)