libs/core: Create get_first() in uci model
[project/luci.git] / applications / luci-olsr / luasrc / model / cbi / olsr / olsrd.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2010 Jo-Philipp Wich <xm@subsignal.org>
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11         http://www.apache.org/licenses/LICENSE-2.0
12
13 $Id$
14 ]]--
15
16 require("luci.tools.webadmin")
17
18 m = Map("olsrd", translate("OLSR Daemon"),
19         translate("The OLSR daemon is an implementation of the Optimized Link State Routing protocol. "..
20         "As such it allows mesh routing for any network equipment. "..
21         "It runs on any wifi card that supports ad-hoc mode and of course on any ethernet device. "..
22         "Visit <a href='http://www.olsr.org'>olsrd.org</a> for help and documentation."))
23
24 function m.on_parse()
25         local has_defaults = false
26
27         m.uci:foreach("olsrd", "InterfaceDefaults",
28                 function(s)
29                         has_defaults = true
30                         return false
31                 end)
32
33         if not has_defaults then
34                 m.uci:section("olsrd", "InterfaceDefaults")
35         end
36 end
37
38 function write_float(self, section, value)
39     local n = tonumber(value)
40     if n ~= nil then
41         return Value.write(self, section, "%.1f" % n) 
42     end
43 end
44
45 s = m:section(TypedSection, "olsrd", translate("General settings"))
46 s.anonymous = true
47
48 s:tab("general",  translate("General Settings"))
49 s:tab("lquality", translate("Link Quality Settings"))
50 s:tab("advanced", translate("Advanced Settings"))
51
52
53 ipv = s:taboption("general", ListValue, "IpVersion", translate("Internet protocol"),
54         translate("IP-version to use. If 6and4 is selected then one olsrd instance is started for each protocol."))
55 ipv:value("4", "IPv4")
56 ipv:value("6", "IPv6")
57 ipv:value("6and4", "6and4")
58
59
60 poll = s:taboption("advanced", Value, "Pollrate", translate("Pollrate"),
61         translate("Polling rate for OLSR sockets in seconds. Default is 0.05."))
62 poll.optional = true
63 poll.datatype = "ufloat"
64 poll.placeholder = "0.05"
65
66 nicc = s:taboption("advanced", Value, "NicChgsPollInt", translate("Nic changes poll interval"),
67         translate("Interval to poll network interfaces for configuration changes (in seconds). Default is \"2.5\"."))
68 nicc.optional = true
69 nicc.datatype = "ufloat"
70 nicc.placeholder = "2.5"
71
72 tos = s:taboption("advanced", Value, "TosValue", translate("TOS value"),
73         translate("Type of service value for the IP header of control traffic. Default is \"16\"."))
74 tos.optional = true
75 tos.datatype = "uinteger"
76 tos.placeholder = "16"
77
78 fib = s:taboption("general", ListValue, "FIBMetric", translate("FIB metric"),
79         translate ("FIBMetric controls the metric value of the host-routes OLSRd sets. "..
80         "\"flat\" means that the metric value is always 2. This is the preferred value "..
81         "because it helps the linux kernel routing to clean up older routes. "..
82         "\"correct\" uses the hopcount as the metric value. "..
83         "\"approx\" use the hopcount as the metric value too, but does only update the hopcount if the nexthop changes too. "..
84         "Default is \"flat\"."))
85 fib:value("flat")
86 fib:value("correct")
87 fib:value("approx")
88
89 lql = s:taboption("lquality", ListValue, "LinkQualityLevel", translate("LQ level"),
90         translate("Link quality level switch between hopcount and cost-based (mostly ETX) routing.<br />"..
91         "<b>0</b> = do not use link quality<br />"..
92         "<b>2</b> = use link quality for MPR selection and routing<br />"..
93         "Default is \"2\""))
94 lql:value("2")
95 lql:value("0")
96
97 lqage = s:taboption("lquality", Value, "LinkQualityAging", translate("LQ aging"),
98         translate("Link quality aging factor (only for lq level 2). Tuning parameter for etx_float and etx_fpm, smaller values "..
99         "mean slower changes of ETX value. (allowed values are between 0.01 and 1.0)"))
100 lqage.optional = true
101 lqage:depends("LinkQualityLevel", "2")
102
103 lqa = s:taboption("lquality", ListValue, "LinkQualityAlgorithm", translate("LQ algorithm"),
104         translate("Link quality algorithm (only for lq level 2).<br />"..
105         "<b>etx_float</b>: floating point ETX with exponential aging<br />"..
106         "<b>etx_fpm</b>  : same as ext_float, but with integer arithmetic<br />"..
107         "<b>etx_ff</b>   : ETX freifunk, an etx variant which use all OLSR traffic (instead of only hellos) for ETX calculation<br />"..
108         "<b>etx_ffeth</b>: incompatible variant of etx_ff that allows ethernet links with ETX 0.1.<br />"..
109         "Defaults to \"etx_ff\""))
110 lqa.optional = true
111 lqa:value("etx_ff")
112 lqa:value("etx_fpm")
113 lqa:value("etx_float")
114 lqa:value("etx_ffeth")
115 lqa:depends("LinkQualityLevel", "2")
116 lqa.optional = true
117
118 lqfish = s:taboption("lquality", Flag, "LinkQualityFishEye", translate("LQ fisheye"),
119         translate("Fisheye mechanism for TCs (checked means on). Default is \"on\""))
120 lqfish.default = "1"
121 lqfish.optional = true
122
123 hyst = s:taboption("lquality", Flag, "UseHysteresis", translate("Use hysteresis"),
124         translate("Hysteresis for link sensing (only for hopcount metric). Hysteresis adds more robustness to the link sensing "..
125         "but delays neighbor registration. Defaults is \"yes\""))
126 hyst.default = "yes"
127 hyst.enabled = "yes"
128 hyst.disabled = "no"
129 hyst:depends("LinkQualityLevel", "0")
130 hyst.optional = true
131 hyst.rmempty = true
132
133 port = s:taboption("general", Value, "OlsrPort", translate("Port"),
134         translate("The port OLSR uses. This should usually stay at the IANA assigned port 698. It can have a value between 1 and 65535."))
135 port.optional = true
136 port.default = "698"
137 port.rmempty = true
138
139 mainip = s:taboption("general", Value, "MainIp", translate("Main IP"),
140         translate("Sets the main IP (originator ip) of the router. This IP will NEVER change during the uptime of olsrd. "..
141         "Default is 0.0.0.0, which triggers usage of the IP of the first interface."))
142 mainip.optional = true
143 mainip.rmempty = true
144 mainip.datatype = "ipaddr"
145 mainip.placeholder = "0.0.0.0"
146
147 willingness = s:taboption("advanced", ListValue, "Willingness", translate("Willingness"),
148                 translate("The fixed willingness to use. If not set willingness will be calculated dynamically based on battery/power status. Default is \"3\"."))
149 for i=0,7 do
150         willingness:value(i)
151 end
152 willingness.optional = true
153 willingness.default = "3"
154
155 natthr = s:taboption("advanced", Value, "NatThreshold", translate("NAT threshold"),
156         translate("If the route to the current gateway is to be changed, the ETX value of this gateway is "..
157         "multiplied with this value before it is compared to the new one. "..
158         "The parameter can be a value between 0.1 and 1.0, but should be close to 1.0 if changed.<br />"..
159         "<b>WARNING:</b> This parameter should not be used together with the etx_ffeth metric!<br />"..
160         "Defaults to \"1.0\"."))
161 for i=1,0.1,-0.1 do
162         natthr:value(i)
163 end
164 natthr:depends("LinkQualityAlgorithm", "etx_ff")
165 natthr:depends("LinkQualityAlgorithm", "etx_float")
166 natthr:depends("LinkQualityAlgorithm", "etx_fpm")
167 natthr.default = "1.0"
168 natthr.optional = true
169 natthr.write = write_float
170
171
172 i = m:section(TypedSection, "InterfaceDefaults", translate("Interfaces Defaults"))
173 i.anonymous = true
174 i.addremove = false
175
176 i:tab("general", translate("General Settings"))
177 i:tab("addrs",   translate("IP Addresses"))
178 i:tab("timing",  translate("Timing and Validity"))
179
180 mode = i:taboption("general", ListValue, "Mode", translate("Mode"),
181         translate("Interface Mode is used to prevent unnecessary packet forwarding on switched ethernet interfaces. "..
182         "valid Modes are \"mesh\" and \"ether\". Default is \"mesh\"."))
183 mode:value("mesh")
184 mode:value("ether")
185 mode.optional = true
186 mode.rmempty = true
187
188
189 weight = i:taboption("general", Value, "Weight", translate("Weight"),
190         translate("When multiple links exist between hosts the weight of interface is used to determine the link to use. "..
191         "Normally the weight is automatically calculated by olsrd based on the characteristics of the interface, "..
192         "but here you can specify a fixed value. Olsrd will choose links with the lowest value.<br />"..
193         "<b>Note:</b> Interface weight is used only when LinkQualityLevel is set to 0. "..
194         "For any other value of LinkQualityLevel, the interface ETX value is used instead."))
195 weight.optional = true
196 weight.datatype = "uinteger"
197 weight.placeholder = "0"
198
199 lqmult = i:taboption("general", DynamicList, "LinkQualityMult", translate("LinkQuality Multiplicator"),
200         translate("Multiply routes with the factor given here. Allowed values are between 0.01 and 1. "..
201         "It is only used when LQ-Level is greater than 0. Examples:<br />"..
202         "reduce LQ to 192.168.0.1 by half: 192.168.0.1 0.5<br />"..
203         "reduce LQ to all nodes on this interface by 20%: default 0.8"))
204 lqmult.optional = true
205 lqmult.rmempty = true
206 lqmult.cast = "table"
207 lqmult.placeholder = "default 1.0"
208
209
210 ip4b = i:taboption("addrs", Value, "Ip4Broadcast", translate("IPv4 broadcast"),
211         translate("IPv4 broadcast address for outgoing OLSR packets. One useful example would be 255.255.255.255. "..
212         "Default is \"0.0.0.0\", which triggers the usage of the interface broadcast IP."))
213 ip4b.optional = true
214 ip4b.datatype = "ip4addr"
215 ip4b.placeholder = "0.0.0.0"
216
217 ip6m = i:taboption("addrs", Value, "IPv6Multicast", translate("IPv6 multicast"),
218         translate("IPv6 multicast address. Default is \"FF02::6D\", the manet-router linklocal multicast."))
219 ip6m.optional = true
220 ip6m.datatype = "ip6addr"
221 ip6m.placeholder = "FF02::6D"
222
223 ip4s = i:taboption("addrs", Value, "IPv4Src", translate("IPv4 source"),
224         translate("IPv4 src address for outgoing OLSR packages. Default is \"0.0.0.0\", which triggers usage of the interface IP."))
225 ip4s.optional = true
226 ip4s.datatype = "ip4addr"
227 ip4s.placeholder = "0.0.0.0"
228
229 ip6s = i:taboption("addrs", Value, "IPv6Src", translate("IPv6 source"),
230         translate("IPv6 src prefix. OLSRd will choose one of the interface IPs which matches the prefix of this parameter. "..
231         "Default is \"0::/0\", which triggers the usage of a not-linklocal interface IP."))
232 ip6s.optional = true
233 ip6s.datatype = "ip6addr"
234 ip6s.placeholder = "0::/0"
235
236
237 hi = i:taboption("timing", Value, "HelloInterval", translate("Hello interval"))
238 hi.optional = true
239 hi.datatype = "ufloat"
240 hi.placeholder = "5.0"
241 hi.write = write_float
242
243 hv = i:taboption("timing", Value, "HelloValidityTime", translate("Hello validity time"))
244 hv.optional = true
245 hv.datatype = "ufloat"
246 hv.placeholder = "40.0"
247 hv.write = write_float
248
249 ti = i:taboption("timing", Value, "TcInterval", translate("TC interval"))
250 ti.optional = true
251 ti.datatype = "ufloat"
252 ti.placeholder = "2.0"
253 ti.write = write_float
254
255 tv = i:taboption("timing", Value, "TcValidityTime", translate("TC validity time"))
256 tv.optional = true
257 tv.datatype = "ufloat"
258 tv.placeholder = "256.0"
259 tv.write = write_float
260
261 mi = i:taboption("timing", Value, "MidInterval", translate("MID interval"))
262 mi.optional = true
263 mi.datatype = "ufloat"
264 mi.placeholder = "18.0"
265 mi.write = write_float
266
267 mv = i:taboption("timing", Value, "MidValidityTime", translate("MID validity time"))
268 mv.optional = true
269 mv.datatype = "ufloat"
270 mv.placeholder = "324.0"
271 mv.write = write_float
272
273 ai = i:taboption("timing", Value, "HnaInterval", translate("HNA interval"))
274 ai.optional = true
275 ai.datatype = "ufloat"
276 ai.placeholder = "18.0"
277 ai.write = write_float
278
279 av = i:taboption("timing", Value, "HnaValidityTime", translate("HNA validity time"))
280 av.optional = true
281 av.datatype = "ufloat"
282 av.placeholder = "108.0"
283 av.write = write_float
284
285
286 ifs = m:section(TypedSection, "Interface", translate("Interfaces"))
287 ifs.addremove = true
288 ifs.anonymous = true
289 ifs.extedit   = luci.dispatcher.build_url("admin/services/olsrd/iface/%s")
290 ifs.template  = "cbi/tblsection"
291
292 function ifs.create(...)
293         local sid = TypedSection.create(...)
294         luci.http.redirect(ifs.extedit % sid)
295 end
296
297 ign = ifs:option(Flag, "ignore", translate("Enable"))
298 ign.enabled  = "0"
299 ign.disabled = "1"
300 ign.rmempty = false
301 function ign.cfgvalue(self, section)
302         return Flag.cfgvalue(self, section) or "0"
303 end
304
305 network = ifs:option(DummyValue, "interface", translate("Network"))
306 network.template = "cbi/network_netinfo"
307
308 mode = ifs:option(DummyValue, "Mode", translate("Mode"))
309 function mode.cfgvalue(...)
310         return Value.cfgvalue(...) or "mesh"
311 end
312
313 hello = ifs:option(DummyValue, "_hello", translate("Hello"))
314 function hello.cfgvalue(self, section)
315         local i = tonumber(m.uci:get("olsrd", section, "HelloInterval"))     or 5
316         local v = tonumber(m.uci:get("olsrd", section, "HelloValidityTime")) or 40
317         return "%.01fs / %.01fs" %{ i, v }
318 end
319
320 tc = ifs:option(DummyValue, "_tc", translate("TC"))
321 function tc.cfgvalue(self, section)
322         local i = tonumber(m.uci:get("olsrd", section, "TcInterval"))     or 2
323         local v = tonumber(m.uci:get("olsrd", section, "TcValidityTime")) or 256
324         return "%.01fs / %.01fs" %{ i, v }
325 end
326
327 mid = ifs:option(DummyValue, "_mid", translate("MID"))
328 function mid.cfgvalue(self, section)
329         local i = tonumber(m.uci:get("olsrd", section, "MidInterval"))     or 18
330         local v = tonumber(m.uci:get("olsrd", section, "MidValidityTime")) or 324
331         return "%.01fs / %.01fs" %{ i, v }
332 end
333
334 hna = ifs:option(DummyValue, "_hna", translate("HNA"))
335 function hna.cfgvalue(self, section)
336         local i = tonumber(m.uci:get("olsrd", section, "HnaInterval"))     or 18
337         local v = tonumber(m.uci:get("olsrd", section, "HnaValidityTime")) or 108
338         return "%.01fs / %.01fs" %{ i, v }
339 end
340
341 return m