1 -- ------ extra functions ------ --
3 function interfaceCheck()
4 metricValue = ut.trim(sys.exec("uci -p /var/state get network." .. arg[1] .. ".metric"))
5 if metricValue == "" then -- no metric
7 else -- if metric exists create list of interface metrics to compare against for duplicates
8 uci.cursor():foreach("mwan3", "interface",
10 local metricValue = ut.trim(sys.exec("uci -p /var/state get network." .. section[".name"] .. ".metric"))
11 metricList = metricList .. section[".name"] .. " " .. metricValue .. "\n"
14 -- compare metric against list
15 local metricDuplicateNumbers, metricDuplicates = sys.exec("echo '" .. metricList .. "' | awk '{print $2}' | uniq -d"), ""
16 for line in metricDuplicateNumbers:gmatch("[^\r\n]+") do
17 metricDuplicates = sys.exec("echo '" .. metricList .. "' | grep '" .. line .. "' | awk '{print $1}'")
18 errorDuplicateMetricList = errorDuplicateMetricList .. metricDuplicates
20 if sys.exec("echo '" .. errorDuplicateMetricList .. "' | grep -w " .. arg[1]) ~= "" then
21 errorDuplicateMetric = 1
24 -- check if this interface has a higher reliability requirement than track IPs configured
25 local trackingNumber = tonumber(ut.trim(sys.exec("echo $(uci -p /var/state get mwan3." .. arg[1] .. ".track_ip) | wc -w")))
26 if trackingNumber > 0 then
27 local reliabilityNumber = tonumber(ut.trim(sys.exec("uci -p /var/state get mwan3." .. arg[1] .. ".reliability")))
28 if reliabilityNumber and reliabilityNumber > trackingNumber then
32 -- check if any interfaces are not properly configured in /etc/config/network or have no default route in main routing table
33 if ut.trim(sys.exec("uci -p /var/state get network." .. arg[1])) == "interface" then
34 local interfaceDevice = ut.trim(sys.exec("uci -p /var/state get network." .. arg[1] .. ".ifname"))
35 if interfaceDevice == "uci: Entry not found" or interfaceDevice == "" then
39 local routeCheck = ut.trim(sys.exec("route -n | awk '{if ($8 == \"" .. interfaceDevice .. "\" && $1 == \"0.0.0.0\" && $3 == \"0.0.0.0\") print $1}'"))
40 if routeCheck == "" then
50 function interfaceWarnings() -- display warning messages at the top of the page
51 local warns, lineBreak = "", ""
52 if errorReliability == 1 then
53 warns = "<font color=\"ff0000\"><strong>" .. translate("WARNING: this interface has a higher reliability requirement than there are tracking IP addresses!") .. "</strong></font>"
54 lineBreak = "<br /><br />"
56 if errorRoute == 1 then
57 warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>" .. translate("WARNING: this interface has no default route in the main routing table!") .. "</strong></font>"
58 lineBreak = "<br /><br />"
60 if errorNetConfig == 1 then
61 warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>" .. translate("WARNING: this interface is configured incorrectly or not at all in /etc/config/network!") .. "</strong></font>"
62 lineBreak = "<br /><br />"
64 if errorNoMetric == 1 then
65 warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>" .. translate("WARNING: this interface has no metric configured in /etc/config/network!") .. "</strong></font>"
66 elseif errorDuplicateMetric == 1 then
67 warns = warns .. lineBreak .. "<font color=\"ff0000\"><strong>" .. translate("WARNING: this and other interfaces have duplicate metrics configured in /etc/config/network!") .. "</strong></font>"
72 -- ------ interface configuration ------ --
74 dsp = require "luci.dispatcher"
75 sys = require "luci.sys"
76 ut = require "luci.util"
81 errorDuplicateMetricList = ""
83 errorDuplicateMetric = 0
90 m5 = Map("mwan3", translatef("MWAN Interface Configuration - %s", arg[1]),
92 m5.redirect = dsp.build_url("admin", "network", "mwan", "configuration", "interface")
95 mwan_interface = m5:section(NamedSection, arg[1], "interface", "")
96 mwan_interface.addremove = false
97 mwan_interface.dynamic = false
100 enabled = mwan_interface:option(ListValue, "enabled", translate("Enabled"))
101 enabled.default = "1"
102 enabled:value("1", translate("Yes"))
103 enabled:value("0", translate("No"))
105 family = mwan_interface:option(ListValue, "family", translate("Internet Protocol"))
106 family.default = "ipv4"
107 family:value("ipv4", translate("IPv4"))
108 family:value("ipv6", translate("IPv6"))
110 track_ip = mwan_interface:option(DynamicList, "track_ip", translate("Tracking hostname or IP address"),
111 translate("This hostname or IP address will be pinged to determine if the link is up or down. Leave blank to assume interface is always online"))
112 track_ip.datatype = "host"
114 reliability = mwan_interface:option(Value, "reliability", translate("Tracking reliability"),
115 translate("Acceptable values: 1-100. This many Tracking IP addresses must respond for the link to be deemed up"))
116 reliability.datatype = "range(1, 100)"
117 reliability.default = "1"
119 count = mwan_interface:option(ListValue, "count", translate("Ping count"))
127 size = mwan_interface:option(Value, "size", translate("Ping size"))
138 size.datatype = "range(1, 65507)"
140 size.optional = false
142 timeout = mwan_interface:option(ListValue, "timeout", translate("Ping timeout"))
143 timeout.default = "2"
144 timeout:value("1", translatef("%d second", 1))
145 timeout:value("2", translatef("%d seconds", 2))
146 timeout:value("3", translatef("%d seconds", 3))
147 timeout:value("4", translatef("%d seconds", 4))
148 timeout:value("5", translatef("%d seconds", 5))
149 timeout:value("6", translatef("%d seconds", 6))
150 timeout:value("7", translatef("%d seconds", 7))
151 timeout:value("8", translatef("%d seconds", 8))
152 timeout:value("9", translatef("%d seconds", 9))
153 timeout:value("10", translatef("%d seconds", 10))
155 interval = mwan_interface:option(ListValue, "interval", translate("Ping interval"))
156 interval.default = "5"
157 interval:value("1", translatef("%d second", 1))
158 interval:value("3", translatef("%d seconds", 3))
159 interval:value("5", translatef("%d seconds", 5))
160 interval:value("10", translatef("%d seconds", 10))
161 interval:value("20", translatef("%d seconds", 20))
162 interval:value("30", translatef("%d seconds", 30))
163 interval:value("60", translatef("%d minute", 1))
164 interval:value("300", translatef("%d minutes", 5))
165 interval:value("600", translatef("%d minutes", 10))
166 interval:value("900", translatef("%d minutes", 15))
167 interval:value("1800", translatef("%d minutes", 30))
168 interval:value("3600", translatef("%d hour", 1))
170 failure = mwan_interface:option(Value, "failure_interval", translate("Failure interval"),
171 translate("Ping interval during failure detection"))
172 failure.default = "5"
173 failure:value("1", translatef("%d second", 1))
174 failure:value("3", translatef("%d seconds", 3))
175 failure:value("5", translatef("%d seconds", 5))
176 failure:value("10", translatef("%d seconds", 10))
177 failure:value("20", translatef("%d seconds", 20))
178 failure:value("30", translatef("%d seconds", 30))
179 failure:value("60", translatef("%d minute", 1))
180 failure:value("300", translatef("%d minutes", 5))
181 failure:value("600", translatef("%d minutes", 10))
182 failure:value("900", translatef("%d minutes", 15))
183 failure:value("1800", translatef("%d minutes", 30))
184 failure:value("3600", translatef("%d hour", 1))
186 recovery = mwan_interface:option(Value, "recovery_interval", translate("Recovery interval"),
187 translate("Ping interval during failure recovering"))
188 recovery.default = "5"
189 recovery:value("1", translatef("%d second", 1))
190 recovery:value("3", translatef("%d seconds", 3))
191 recovery:value("5", translatef("%d seconds", 5))
192 recovery:value("10", translatef("%d seconds", 10))
193 recovery:value("20", translatef("%d seconds", 20))
194 recovery:value("30", translatef("%d seconds", 30))
195 recovery:value("60", translatef("%d minute", 1))
196 recovery:value("300", translatef("%d minutes", 5))
197 recovery:value("600", translatef("%d minutes", 10))
198 recovery:value("900", translatef("%d minutes", 15))
199 recovery:value("1800", translatef("%d minutes", 30))
200 recovery:value("3600", translatef("%d hour", 1))
202 down = mwan_interface:option(ListValue, "down", translate("Interface down"),
203 translate("Interface will be deemed down after this many failed ping tests"))
216 up = mwan_interface:option(ListValue, "up", translate("Interface up"),
217 translate("Downed interface will be deemed up after this many successful ping tests"))
230 flush = mwan_interface:option(ListValue, "flush_conntrack", translate("Flush conntrack table"),
231 translate("Flush global firewall conntrack table on interface events"))
232 flush.default = "never"
233 flush:value("ifup", translate("ifup"))
234 flush:value("ifdown", translate("ifdown"))
235 flush:value("never", translate("never"))
236 flush:value("always", translate("always"))
238 metric = mwan_interface:option(DummyValue, "metric", translate("Metric"),
239 translate("This displays the metric assigned to this interface in /etc/config/network"))
240 metric.rawhtml = true
241 function metric.cfgvalue(self, s)
242 if errorNoMetric == 0 then