Merge pull request #1426 from dibdot/app-adblock
[project/luci.git] / applications / luci-app-mwan3 / luasrc / model / cbi / mwan / interface.lua
1 -- ------ extra functions ------ --
2
3 function interfaceCheck() -- find issues with too many interfaces, reliability and metric
4         uci.cursor():foreach("mwan3", "interface",
5                 function (section)
6                         local interfaceName = section[".name"]
7                         interfaceNumber = interfaceNumber+1 -- count number of mwan interfaces configured
8                         -- create list of metrics for none and duplicate checking
9                         local metricValue = ut.trim(sys.exec("uci -p /var/state get network." .. interfaceName .. ".metric"))
10                         if metricValue == "" then
11                                 errorFound = 1
12                                 errorNoMetricList = errorNoMetricList .. interfaceName .. " "
13                         else
14                                 metricList = metricList .. interfaceName .. " " .. metricValue .. "\n"
15                         end
16                         -- check if any interfaces have a higher reliability requirement than tracking IPs configured
17                         local trackingNumber = tonumber(ut.trim(sys.exec("echo $(uci -p /var/state get mwan3." .. interfaceName .. ".track_ip) | wc -w")))
18                         if trackingNumber > 0 then
19                                 local reliabilityNumber = tonumber(ut.trim(sys.exec("uci -p /var/state get mwan3." .. interfaceName .. ".reliability")))
20                                 if reliabilityNumber and reliabilityNumber > trackingNumber then
21                                         errorFound = 1
22                                         errorReliabilityList = errorReliabilityList .. interfaceName .. " "
23                                 end
24                         end
25                         -- check if any interfaces are not properly configured in /etc/config/network or have no default route in main routing table
26                         if ut.trim(sys.exec("uci -p /var/state get network." .. interfaceName)) == "interface" then
27                                 local interfaceDevice = ut.trim(sys.exec("uci -p /var/state get network." .. interfaceName .. ".ifname"))
28                                 if interfaceDevice == "uci: Entry not found" or interfaceDevice == "" then
29                                         errorFound = 1
30                                         errorNetConfigList = errorNetConfigList .. interfaceName .. " "
31                                         errorRouteList = errorRouteList .. interfaceName .. " "
32                                 else
33                                         local routeCheck = ut.trim(sys.exec("route -n | awk '{if ($8 == \"" .. interfaceDevice .. "\" && $1 == \"0.0.0.0\" && $3 == \"0.0.0.0\") print $1}'"))
34                                         if routeCheck == "" then
35                                                 errorFound = 1
36                                                 errorRouteList = errorRouteList .. interfaceName .. " "
37                                         end
38                                 end
39                         else
40                                 errorFound = 1
41                                 errorNetConfigList = errorNetConfigList .. interfaceName .. " "
42                                 errorRouteList = errorRouteList .. interfaceName .. " "
43                         end
44                 end
45         )
46         -- check if any interfaces have duplicate metrics
47         local metricDuplicateNumbers = sys.exec("echo '" .. metricList .. "' | awk '{print $2}' | uniq -d")
48         if metricDuplicateNumbers ~= "" then
49                 errorFound = 1
50                 local metricDuplicates = ""
51                 for line in metricDuplicateNumbers:gmatch("[^\r\n]+") do
52                         metricDuplicates = sys.exec("echo '" .. metricList .. "' | grep '" .. line .. "' | awk '{print $1}'")
53                         errorDuplicateMetricList = errorDuplicateMetricList .. metricDuplicates
54                 end
55                 errorDuplicateMetricList = sys.exec("echo '" .. errorDuplicateMetricList .. "' | tr '\n' ' '")
56         end
57 end
58
59 function interfaceWarnings() -- display status and warning messages at the top of the page
60         local warnings = ""
61         if interfaceNumber <= 250 then
62                 warnings = "<strong>" .. translatef("There are currently %d of 250 supported interfaces configured", interfaceNumber) .. "</strong>"
63         else
64                 warnings = "<font color=\"ff0000\"><strong>" .. translatef("WARNING: %d interfaces are configured exceeding the maximum of 250!", interfaceNumber) .. "</strong></font>"
65         end
66         if errorReliabilityList ~= " " then
67                 warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>" .. translate("WARNING: Some interfaces have a higher reliability requirement than there are tracking IP addresses!") .. "</strong></font>"
68         end
69         if errorRouteList ~= " " then
70                 warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>" .. translate("WARNING: Some interfaces have no default route in the main routing table!") .. "</strong></font>"
71         end
72         if errorNetConfigList ~= " " then
73                 warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>" .. translate("WARNING: Some interfaces are configured incorrectly or not at all in /etc/config/network!") .. "</strong></font>"
74         end
75         if errorNoMetricList ~= " " then
76                 warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>" .. translate("WARNING: Some interfaces have no metric configured in /etc/config/network!") .. "</strong></font>"
77         end
78         if errorDuplicateMetricList ~= " " then
79                 warnings = warnings .. "<br /><br /><font color=\"ff0000\"><strong>" .. translate("WARNING: Some interfaces have duplicate metrics configured in /etc/config/network!") .. "</strong></font>"
80         end
81         return warnings
82 end
83
84 -- ------ interface configuration ------ --
85
86 dsp = require "luci.dispatcher"
87 sys = require "luci.sys"
88 ut = require "luci.util"
89
90 interfaceNumber = 0
91 metricList = ""
92 errorFound = 0
93 errorDuplicateMetricList = " "
94 errorNetConfigList = " "
95 errorNoMetricList = " "
96 errorReliabilityList = " "
97 errorRouteList = " "
98 interfaceCheck()
99
100
101 m5 = Map("mwan3", translate("MWAN Interface Configuration"),
102         interfaceWarnings())
103         m5:append(Template("mwan/config_css"))
104
105
106 mwan_interface = m5:section(TypedSection, "interface", translate("Interfaces"),
107         translate("MWAN supports up to 250 physical and/or logical interfaces<br />" ..
108         "MWAN requires that all interfaces have a unique metric configured in /etc/config/network<br />" ..
109         "Names must match the interface name found in /etc/config/network (see advanced tab)<br />" ..
110         "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" ..
111         "Interfaces may not share the same name as configured members, policies or rules"))
112         mwan_interface.addremove = true
113         mwan_interface.dynamic = false
114         mwan_interface.sectionhead = translate("Interface")
115         mwan_interface.sortable = false
116         mwan_interface.template = "cbi/tblsection"
117         mwan_interface.extedit = dsp.build_url("admin", "network", "mwan", "configuration", "interface", "%s")
118         function mwan_interface.create(self, section)
119                 TypedSection.create(self, section)
120                 m5.uci:save("mwan3")
121                 luci.http.redirect(dsp.build_url("admin", "network", "mwan", "configuration", "interface", section))
122         end
123
124
125 enabled = mwan_interface:option(DummyValue, "enabled", translate("Enabled"))
126         enabled.rawhtml = true
127         function enabled.cfgvalue(self, s)
128                 if self.map:get(s, "enabled") == "1" then
129                         return "Yes"
130                 else
131                         return "No"
132                 end
133         end
134
135 track_ip = mwan_interface:option(DummyValue, "track_ip", translate("Tracking IP"))
136         track_ip.rawhtml = true
137         function track_ip.cfgvalue(self, s)
138                 tracked = self.map:get(s, "track_ip")
139                 if tracked then
140                         local ipList = ""
141                         for k,v in pairs(tracked) do
142                                 ipList = ipList .. v .. "<br />"
143                         end
144                         return ipList
145                 else
146                         return "&#8212;"
147                 end
148         end
149
150 track_method = mwan_interface:option(DummyValue, "track_method", translate("Tracking method"))
151         track_method.rawhtml = true
152         function track_method.cfgvalue(self, s)
153                 if tracked then
154                         return self.map:get(s, "track_method") or "&#8212;"
155                 else
156                         return "&#8212;"
157                 end
158         end
159
160 reliability = mwan_interface:option(DummyValue, "reliability", translate("Tracking reliability"))
161         reliability.rawhtml = true
162         function reliability.cfgvalue(self, s)
163                 if tracked then
164                         return self.map:get(s, "reliability") or "&#8212;"
165                 else
166                         return "&#8212;"
167                 end
168         end
169
170 count = mwan_interface:option(DummyValue, "count", translate("Ping count"))
171         count.rawhtml = true
172         function count.cfgvalue(self, s)
173                 if tracked then
174                         return self.map:get(s, "count") or "&#8212;"
175                 else
176                         return "&#8212;"
177                 end
178         end
179
180 timeout = mwan_interface:option(DummyValue, "timeout", translate("Ping timeout"))
181         timeout.rawhtml = true
182         function timeout.cfgvalue(self, s)
183                 if tracked then
184                         local timeoutValue = self.map:get(s, "timeout")
185                         if timeoutValue then
186                                 return timeoutValue .. "s"
187                         else
188                                 return "&#8212;"
189                         end
190                 else
191                         return "&#8212;"
192                 end
193         end
194
195 interval = mwan_interface:option(DummyValue, "interval", translate("Ping interval"))
196         interval.rawhtml = true
197         function interval.cfgvalue(self, s)
198                 if tracked then
199                         local intervalValue = self.map:get(s, "interval")
200                         if intervalValue then
201                                 return intervalValue .. "s"
202                         else
203                                 return "&#8212;"
204                         end
205                 else
206                         return "&#8212;"
207                 end
208         end
209
210 down = mwan_interface:option(DummyValue, "down", translate("Interface down"))
211         down.rawhtml = true
212         function down.cfgvalue(self, s)
213                 if tracked then
214                         return self.map:get(s, "down") or "&#8212;"
215                 else
216                         return "&#8212;"
217                 end
218         end
219
220 up = mwan_interface:option(DummyValue, "up", translate("Interface up"))
221         up.rawhtml = true
222         function up.cfgvalue(self, s)
223                 if tracked then
224                         return self.map:get(s, "up") or "&#8212;"
225                 else
226                         return "&#8212;"
227                 end
228         end
229
230 metric = mwan_interface:option(DummyValue, "metric", translate("Metric"))
231         metric.rawhtml = true
232         function metric.cfgvalue(self, s)
233                 local metricValue = sys.exec("uci -p /var/state get network." .. s .. ".metric")
234                 if metricValue ~= "" then
235                         return metricValue
236                 else
237                         return "&#8212;"
238                 end
239         end
240
241 errors = mwan_interface:option(DummyValue, "errors", translate("Errors"))
242         errors.rawhtml = true
243         function errors.cfgvalue(self, s)
244                 if errorFound == 1 then
245                         local mouseOver, lineBreak = "", ""
246                         if string.find(errorReliabilityList, " " .. s .. " ") then
247                                 mouseOver = "Higher reliability requirement than there are tracking IP addresses"
248                                 lineBreak = "&#10;&#10;"
249                         end
250                         if string.find(errorRouteList, " " .. s .. " ") then
251                                 mouseOver = mouseOver .. lineBreak .. "No default route in the main routing table"
252                                 lineBreak = "&#10;&#10;"
253                         end
254                         if string.find(errorNetConfigList, " " .. s .. " ") then
255                                 mouseOver = mouseOver .. lineBreak .. "Configured incorrectly or not at all in /etc/config/network"
256                                 lineBreak = "&#10;&#10;"
257                         end
258                         if string.find(errorNoMetricList, " " .. s .. " ") then
259                                 mouseOver = mouseOver .. lineBreak .. "No metric configured in /etc/config/network"
260                                 lineBreak = "&#10;&#10;"
261                         end
262                         if string.find(errorDuplicateMetricList, " " .. s .. " ") then
263                                 mouseOver = mouseOver .. lineBreak .. "Duplicate metric configured in /etc/config/network"
264                         end
265                         if mouseOver == "" then
266                                 return ""
267                         else
268                                 return "<span title=\"" .. mouseOver .. "\"><img src=\"/luci-static/resources/cbi/reset.gif\" alt=\"error\"></img></span>"
269                         end
270                 else
271                         return ""
272                 end
273         end
274
275
276 return m5