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()
73 -- detailed mwan status
74 local detailStatusInfo = ut.trim(sys.exec("/usr/sbin/mwan3 status"))
75 if detailStatusInfo ~= "" then
76 mArray.mwandetail = { detailStatusInfo }
79 luci.http.prepare_content("application/json")
80 luci.http.write_json(mArray)
83 function diagnosticsData(interface, task)
84 function getInterfaceNumber(interface)
87 uci.cursor():foreach("mwan3", "interface",
90 if section[".name"] == interface then
91 interfaceNumber = number
95 return interfaceNumber
98 function diag_command(cmd, addr)
99 if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
100 local util = io.popen(cmd % addr)
103 local ln = util:read("*l")
104 if not ln then break end
106 luci.http.write("\n")
114 function get_gateway(inteface)
115 local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
119 for _, route in ipairs(dump.route) do
120 if dump.route[_].target == "0.0.0.0" then
121 gateway = dump.route[_].nexthop
130 local number = getInterfaceNumber(interface)
132 local uci = uci.cursor(nil, "/var/state")
133 local device = uci:get("network", interface, "ifname")
135 luci.http.prepare_content("text/plain")
137 if task == "ping_gateway" then
138 local gateway = get_gateway(interface)
139 if gateway ~= nil then
140 diag_command("ping -c 5 -W 1 %q 2>&1", gateway)
142 luci.http.prepare_content("text/plain")
143 luci.http.write(string.format("No gateway for interface %s found.", interface))
145 elseif task == "ping_trackips" then
146 local trackips = uci:get("mwan3", interface, "track_ip")
147 if #trackips > 0 then
148 for i in pairs(trackips) do
149 diag_command("ping -c 5 -W 1 %q 2>&1", trackips[i])
152 luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
154 elseif task == "check_rules" then
155 local number = getInterfaceNumber(interface)
156 local iif = 1000 + number
157 local fwmark = 2000 + number
158 local iif_rule = sys.exec(string.format("ip rule | grep %d", iif))
159 local fwmark_rule = sys.exec(string.format("ip rule | grep %d", fwmark))
160 if iif_rule ~= "" and fwmark_rule ~= "" then
161 luci.http.write(string.format("All required IP rules for interface %s found", interface))
162 luci.http.write("\n")
163 luci.http.write(fwmark_rule)
164 luci.http.write(iif_rule)
165 elseif iif_rule == "" and fwmark_rule ~= "" then
166 luci.http.write(string.format("Only one IP rules for interface %s found", interface))
167 luci.http.write("\n")
168 luci.http.write(fwmark_rule)
169 elseif iif_rule ~= "" and fwmark_rule == "" then
170 luci.http.write(string.format("Only one IP rules for interface %s found", interface))
171 luci.http.write("\n")
172 luci.http.write(iif_rule)
174 luci.http.write(string.format("Missing both IP rules for interface %s", interface))
176 elseif task == "check_routes" then
177 local number = getInterfaceNumber(interface)
178 local routeTable = sys.exec(string.format("ip route list table %s", number))
179 if routeTable ~= "" then
180 luci.http.write(string.format("Routing table %s for interface %s found", number, interface))
181 luci.http.write("\n")
182 luci.http.write(routeTable)
184 luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
186 elseif task == "hotplug_ifup" then
187 os.execute(string.format("/usr/sbin/mwan3 ifup %s", interface))
188 luci.http.write(string.format("Hotplug ifup sent to interface %s", interface))
189 elseif task == "hotplug_ifdown" then
190 os.execute(string.format("/usr/sbin/mwan3 ifdown %s", interface))
191 luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface))
193 luci.http.write("Unknown task")
196 luci.http.write(string.format("Unable to perform diagnostic tests on %s.", interface))
197 luci.http.write("\n")
198 luci.http.write("There is no physical or virtual device associated with this interface.")
202 function troubleshootingData()
203 local ver = require "luci.version"
208 local wrtRelease = ut.trim(ver.distversion)
209 if wrtRelease ~= "" then
210 wrtRelease = "OpenWrt - " .. wrtRelease
212 wrtRelease = "OpenWrt - unknown"
214 local luciRelease = ut.trim(ver.luciversion)
215 if luciRelease ~= "" then
216 luciRelease = "\nLuCI - " .. luciRelease
218 luciRelease = "\nLuCI - unknown"
220 local mwanVersion = ut.trim(sys.exec("opkg info mwan3 | grep Version | awk '{print $2}'"))
221 if mwanVersion ~= "" then
222 mwanVersion = "\n\nmwan3 - " .. mwanVersion
224 mwanVersion = "\n\nmwan3 - unknown"
226 local mwanLuciVersion = ut.trim(sys.exec("opkg info luci-app-mwan3 | grep Version | awk '{print $2}'"))
227 if mwanLuciVersion ~= "" then
228 mwanLuciVersion = "\nmwan3-luci - " .. mwanLuciVersion
230 mwanLuciVersion = "\nmwan3-luci - unknown"
232 mArray.versions = { wrtRelease .. luciRelease .. mwanVersion .. mwanLuciVersion }
235 local mwanConfig = ut.trim(sys.exec("cat /etc/config/mwan3"))
236 if mwanConfig == "" then
237 mwanConfig = "No data found"
239 mArray.mwanconfig = { mwanConfig }
242 local networkConfig = ut.trim(sys.exec("cat /etc/config/network | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/'"))
243 if networkConfig == "" then
244 networkConfig = "No data found"
246 mArray.netconfig = { networkConfig }
249 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/'"))
250 if wirelessConfig == "" then
251 wirelessConfig = "No data found"
253 mArray.wificonfig = { wirelessConfig }
256 local ifconfig = ut.trim(sys.exec("ifconfig"))
257 if ifconfig == "" then
258 ifconfig = "No data found"
260 mArray.ifconfig = { ifconfig }
263 local routeShow = ut.trim(sys.exec("route -n"))
264 if routeShow == "" then
265 routeShow = "No data found"
267 mArray.routeshow = { routeShow }
270 local ipRuleShow = ut.trim(sys.exec(ip .. "rule show"))
271 if ipRuleShow == "" then
272 ipRuleShow = "No data found"
274 mArray.iprule = { ipRuleShow }
276 -- ip route list table 1-250
277 local routeList, routeString = ut.trim(sys.exec(ip .. "rule | sed 's/://g' 2>/dev/null | awk '$1>=2001 && $1<=2250' | awk '{print $NF}'")), ""
278 if routeList ~= "" then
279 for line in routeList:gmatch("[^\r\n]+") do
280 routeString = routeString .. line .. "\n" .. sys.exec(ip .. "route list table " .. line)
282 routeString = ut.trim(routeString)
284 routeString = "No data found"
286 mArray.routelist = { routeString }
288 -- default firewall output policy
289 local firewallOut = ut.trim(sys.exec("uci -q -p /var/state get firewall.@defaults[0].output"))
290 if firewallOut == "" then
291 firewallOut = "No data found"
293 mArray.firewallout = { firewallOut }
296 local iptables = ut.trim(sys.exec("iptables -L -t mangle -v -n"))
297 if iptables == "" then
298 iptables = "No data found"
300 mArray.iptables = { iptables }
302 luci.http.prepare_content("application/json")
303 luci.http.write_json(mArray)