14bf1384f78eff1673f07348a2792049794cc4aa
[project/luci.git] / applications / luci-app-mwan3 / luasrc / model / cbi / mwan / interface.lua
1 -- Copyright 2014 Aedan Renner <chipdankly@gmail.com
2 -- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
3 -- Licensed to the public under the GNU General Public License v2.
4
5 dsp = require "luci.dispatcher"
6
7
8 function interfaceWarnings(overview, count)
9 local warnings = ""
10 if count <= 250 then
11 warnings = string.format("<strong>%s</strong><br />",
12 translatef("There are currently %d of 250 supported interfaces configured", count)
13 )
14 else
15 warnings = string.format("<strong>%s</strong><br />",
16 translatef("WARNING: %d interfaces are configured exceeding the maximum of 250!", count)
17 )
18 end
19
20 for i, k in pairs(overview) do
21 if overview[i]["network"] == false then
22 warnings = warnings .. string.format("<strong>%s</strong><br />",
23 translatef("WARNING: Interface %s are not found in /etc/config/network", i)
24 )
25 end
26
27 if overview[i]["default_route"] == false then
28 warnings = warnings .. string.format("<strong>%s</strong><br />",
29 translatef("WARNING: Interface %s has no default route in the main routing table", i)
30 )
31 end
32
33 if overview[i]["reliability"] == false then
34 warnings = warnings .. string.format("<strong>%s</strong><br />",
35 translatef("WARNING: Interface %s has a higher reliability " ..
36 "requirement than tracking hosts (%d)", i, overview[i]["tracking"])
37 )
38 end
39
40 if overview[i]["duplicate_metric"] == true then
41 warnings = warnings .. string.format("<strong>%s</strong><br />",
42 translatef("WARNING: Interface %s has a duplicate metric %s configured", i, overview[i]["metric"])
43 )
44 end
45 end
46
47 return warnings
48 end
49
50 function configCheck()
51 local overview = {}
52 local count = 0
53 local duplicate_metric = {}
54 uci.cursor():foreach("mwan3", "interface",
55 function (section)
56 local uci = uci.cursor(nil, "/var/state")
57 local iface = section[".name"]
58 overview[iface] = {}
59 count = count + 1
60 local network = uci:get("network", iface)
61 overview[iface]["network"] = false
62 if network ~= nil then
63 overview[iface]["network"] = true
64
65 local device = uci:get("network", iface, "ifname")
66 if device ~= nil then
67 overview[iface]["device"] = device
68 end
69
70 local metric = uci:get("network", iface, "metric")
71 if metric ~= nil then
72 overview[iface]["metric"] = metric
73 overview[iface]["duplicate_metric"] = false
74 for _, m in ipairs(duplicate_metric) do
75 if m == metric then
76 overview[iface]["duplicate_metric"] = true
77 end
78 end
79 table.insert(duplicate_metric, metric)
80 end
81
82 local dump = require("luci.util").ubus("network.interface.%s" % iface, "status", {})
83 overview[iface]["default_route"] = false
84 if dump and dump.route then
85 local _, route
86 for _, route in ipairs(dump.route) do
87 if dump.route[_].target == "0.0.0.0" then
88 overview[iface]["default_route"] = true
89 end
90 end
91 end
92 end
93
94 local trackingNumber = uci:get("mwan3", iface, "track_ip")
95 overview[iface]["tracking"] = 0
96 if trackingNumber and #trackingNumber > 0 then
97 overview[iface]["tracking"] = #trackingNumber
98 overview[iface]["reliability"] = false
99 local reliabilityNumber = tonumber(uci:get("mwan3", iface, "reliability"))
100 if reliabilityNumber and reliabilityNumber <= #trackingNumber then
101 overview[iface]["reliability"] = true
102 end
103 end
104 end
105 )
106 return overview, count
107 end
108
109 m5 = Map("mwan3", translate("MWAN - Interfaces"),
110 interfaceWarnings(configCheck()))
111
112 mwan_interface = m5:section(TypedSection, "interface", nil,
113 translate("MWAN supports up to 250 physical and/or logical interfaces<br />" ..
114 "MWAN requires that all interfaces have a unique metric configured in /etc/config/network<br />" ..
115 "Names must match the interface name found in /etc/config/network (see advanced tab)<br />" ..
116 "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" ..
117 "Interfaces may not share the same name as configured members, policies or rules"))
118 mwan_interface.addremove = true
119 mwan_interface.dynamic = false
120 mwan_interface.sectionhead = translate("Interface")
121 mwan_interface.sortable = false
122 mwan_interface.template = "cbi/tblsection"
123 mwan_interface.extedit = dsp.build_url("admin", "network", "mwan", "interface", "%s")
124 function mwan_interface.create(self, section)
125 TypedSection.create(self, section)
126 m5.uci:save("mwan3")
127 luci.http.redirect(dsp.build_url("admin", "network", "mwan", "interface", section))
128 end
129
130 enabled = mwan_interface:option(DummyValue, "enabled", translate("Enabled"))
131 enabled.rawhtml = true
132 function enabled.cfgvalue(self, s)
133 if self.map:get(s, "enabled") == "1" then
134 return translate("Yes")
135 else
136 return translate("No")
137 end
138 end
139
140 track_method = mwan_interface:option(DummyValue, "track_method", translate("Tracking method"))
141 track_method.rawhtml = true
142 function track_method.cfgvalue(self, s)
143 local tracked = self.map:get(s, "track_ip")
144 if tracked then
145 return self.map:get(s, "track_method") or "&#8212;"
146 else
147 return "&#8212;"
148 end
149 end
150
151 reliability = mwan_interface:option(DummyValue, "reliability", translate("Tracking reliability"))
152 reliability.rawhtml = true
153 function reliability.cfgvalue(self, s)
154 local tracked = self.map:get(s, "track_ip")
155 if tracked then
156 return self.map:get(s, "reliability") or "&#8212;"
157 else
158 return "&#8212;"
159 end
160 end
161
162 interval = mwan_interface:option(DummyValue, "interval", translate("Ping interval"))
163 interval.rawhtml = true
164 function interval.cfgvalue(self, s)
165 local tracked = self.map:get(s, "track_ip")
166 if tracked then
167 local intervalValue = self.map:get(s, "interval")
168 if intervalValue then
169 return intervalValue .. "s"
170 else
171 return "&#8212;"
172 end
173 else
174 return "&#8212;"
175 end
176 end
177
178 down = mwan_interface:option(DummyValue, "down", translate("Interface down"))
179 down.rawhtml = true
180 function down.cfgvalue(self, s)
181 local tracked = self.map:get(s, "track_ip")
182 if tracked then
183 return self.map:get(s, "down") or "&#8212;"
184 else
185 return "&#8212;"
186 end
187 end
188
189 up = mwan_interface:option(DummyValue, "up", translate("Interface up"))
190 up.rawhtml = true
191 function up.cfgvalue(self, s)
192 local tracked = self.map:get(s, "track_ip")
193 if tracked then
194 return self.map:get(s, "up") or "&#8212;"
195 else
196 return "&#8212;"
197 end
198 end
199
200 metric = mwan_interface:option(DummyValue, "metric", translate("Metric"))
201 metric.rawhtml = true
202 function metric.cfgvalue(self, s)
203 local uci = uci.cursor(nil, "/var/state")
204 local metric = uci:get("network", s, "metric")
205 if metric then
206 return metric
207 else
208 return "&#8212;"
209 end
210 end
211
212 return m5