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