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 initial_state = mwan_interface:option(ListValue, "initial_state", translate("Initial state"),
106 translate("Expect interface state on up event"))
107 initial_state.default = "online"
108 initial_state:value("online", translate("Online"))
109 initial_state:value("offline", translate("Offline"))
111 family = mwan_interface:option(ListValue, "family", translate("Internet Protocol"))
112 family.default = "ipv4"
113 family:value("ipv4", translate("IPv4"))
114 family:value("ipv6", translate("IPv6"))
116 track_ip = mwan_interface:option(DynamicList, "track_ip", translate("Tracking hostname or IP address"),
117 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"))
118 track_ip.datatype = "host"
120 track_method = mwan_interface:option(ListValue, "track_method", translate("Tracking method"))
121 track_method.default = "ping"
122 track_method:value("ping")
123 track_method:value("arping")
124 track_method:value("httping")
126 reliability = mwan_interface:option(Value, "reliability", translate("Tracking reliability"),
127 translate("Acceptable values: 1-100. This many Tracking IP addresses must respond for the link to be deemed up"))
128 reliability.datatype = "range(1, 100)"
129 reliability.default = "1"
131 count = mwan_interface:option(ListValue, "count", translate("Ping count"))
139 size = mwan_interface:option(Value, "size", translate("Ping size"))
150 size.datatype = "range(1, 65507)"
152 size.optional = false
154 timeout = mwan_interface:option(ListValue, "timeout", translate("Ping timeout"))
155 timeout.default = "2"
156 timeout:value("1", translatef("%d second", 1))
157 timeout:value("2", translatef("%d seconds", 2))
158 timeout:value("3", translatef("%d seconds", 3))
159 timeout:value("4", translatef("%d seconds", 4))
160 timeout:value("5", translatef("%d seconds", 5))
161 timeout:value("6", translatef("%d seconds", 6))
162 timeout:value("7", translatef("%d seconds", 7))
163 timeout:value("8", translatef("%d seconds", 8))
164 timeout:value("9", translatef("%d seconds", 9))
165 timeout:value("10", translatef("%d seconds", 10))
167 interval = mwan_interface:option(ListValue, "interval", translate("Ping interval"))
168 interval.default = "5"
169 interval:value("1", translatef("%d second", 1))
170 interval:value("3", translatef("%d seconds", 3))
171 interval:value("5", translatef("%d seconds", 5))
172 interval:value("10", translatef("%d seconds", 10))
173 interval:value("20", translatef("%d seconds", 20))
174 interval:value("30", translatef("%d seconds", 30))
175 interval:value("60", translatef("%d minute", 1))
176 interval:value("300", translatef("%d minutes", 5))
177 interval:value("600", translatef("%d minutes", 10))
178 interval:value("900", translatef("%d minutes", 15))
179 interval:value("1800", translatef("%d minutes", 30))
180 interval:value("3600", translatef("%d hour", 1))
182 failure = mwan_interface:option(Value, "failure_interval", translate("Failure interval"),
183 translate("Ping interval during failure detection"))
184 failure.default = "5"
185 failure:value("1", translatef("%d second", 1))
186 failure:value("3", translatef("%d seconds", 3))
187 failure:value("5", translatef("%d seconds", 5))
188 failure:value("10", translatef("%d seconds", 10))
189 failure:value("20", translatef("%d seconds", 20))
190 failure:value("30", translatef("%d seconds", 30))
191 failure:value("60", translatef("%d minute", 1))
192 failure:value("300", translatef("%d minutes", 5))
193 failure:value("600", translatef("%d minutes", 10))
194 failure:value("900", translatef("%d minutes", 15))
195 failure:value("1800", translatef("%d minutes", 30))
196 failure:value("3600", translatef("%d hour", 1))
198 keep_failure = mwan_interface:option(Flag, "keep_failure_interval", translate("Keep failure interval"),
199 translate("Keep ping failure interval during failure state"))
200 keep_failure.default = keep_failure.disabled
202 recovery = mwan_interface:option(Value, "recovery_interval", translate("Recovery interval"),
203 translate("Ping interval during failure recovering"))
204 recovery.default = "5"
205 recovery:value("1", translatef("%d second", 1))
206 recovery:value("3", translatef("%d seconds", 3))
207 recovery:value("5", translatef("%d seconds", 5))
208 recovery:value("10", translatef("%d seconds", 10))
209 recovery:value("20", translatef("%d seconds", 20))
210 recovery:value("30", translatef("%d seconds", 30))
211 recovery:value("60", translatef("%d minute", 1))
212 recovery:value("300", translatef("%d minutes", 5))
213 recovery:value("600", translatef("%d minutes", 10))
214 recovery:value("900", translatef("%d minutes", 15))
215 recovery:value("1800", translatef("%d minutes", 30))
216 recovery:value("3600", translatef("%d hour", 1))
218 down = mwan_interface:option(ListValue, "down", translate("Interface down"),
219 translate("Interface will be deemed down after this many failed ping tests"))
232 up = mwan_interface:option(ListValue, "up", translate("Interface up"),
233 translate("Downed interface will be deemed up after this many successful ping tests"))
246 flush = mwan_interface:option(ListValue, "flush_conntrack", translate("Flush conntrack table"),
247 translate("Flush global firewall conntrack table on interface events"))
248 flush.default = "never"
249 flush:value("ifup", translate("ifup"))
250 flush:value("ifdown", translate("ifdown"))
251 flush:value("never", translate("never"))
252 flush:value("always", translate("always"))
254 metric = mwan_interface:option(DummyValue, "metric", translate("Metric"),
255 translate("This displays the metric assigned to this interface in /etc/config/network"))
256 metric.rawhtml = true
257 function metric.cfgvalue(self, s)
258 if errorNoMetric == 0 then