luci-olsr split IPv6/4 configuration in 2 sections

This commit is contained in:
Patrick Grimm 2014-07-30 19:11:04 +00:00
parent 33d88f9b54
commit 2332a0692c
10 changed files with 993 additions and 50 deletions

View file

@ -2,5 +2,6 @@
[ -n "${IPKG_INSTROOT}" ] || {
( . /etc/uci-defaults/luci-olsr ) && rm -f /etc/uci-defaults/luci-olsr
/etc/init.d/olsrd enabled || /etc/init.d/olsrd enable
/etc/init.d/olsrd6 enabled || /etc/init.d/olsrd6 enable
exit 0
}

View file

@ -1,7 +1,14 @@
module("luci.controller.olsr", package.seeall)
function index()
if not nixio.fs.access("/etc/config/olsrd") then
local ipv4,ipv6
if nixio.fs.access("/etc/config/olsrd") then
ipv4 = 1
end
if nixio.fs.access("/etc/config/olsrd6") then
ipv6 = 1
end
if not ipv4 and not ipv6 then
return
end
@ -60,46 +67,11 @@ function index()
page.title = _("Interfaces")
page.order = 70
local ol = entry(
{"admin", "services", "olsrd"},
cbi("olsr/olsrd"), "OLSR"
)
ol.subindex = true
entry(
{"admin", "services", "olsrd", "iface"},
cbi("olsr/olsrdiface")
).leaf = true
entry(
{"admin", "services", "olsrd", "hna"},
cbi("olsr/olsrdhna"), _("HNA Announcements")
)
oplg = entry(
{"admin", "services", "olsrd", "plugins"},
cbi("olsr/olsrdplugins"), _("Plugins")
)
odsp = entry(
{"admin", "services", "olsrd", "display"},
cbi("olsr/olsrddisplay"), _("Display")
)
oplg.leaf = true
oplg.subindex = true
local uci = require("luci.model.uci").cursor()
uci:foreach("olsrd", "LoadPlugin",
function (section)
local lib = section.library
entry(
{"admin", "services", "olsrd", "plugins", lib },
cbi("olsr/olsrdplugins"),
nil --'Plugin "%s"' % lib:gsub("^olsrd_",""):gsub("%.so.+$","")
)
end
)
end
function action_json()
@ -109,13 +81,8 @@ function action_json()
local jsonreq4
local jsonreq6
local IpVersion = uci:get_first("olsrd", "olsrd","IpVersion")
if IpVersion == "4" or IpVersion == "6and4" then
jsonreq4 = utl.exec("echo /status | nc 127.0.0.1 9090")
end
if IpVersion == "6" or IpVersion == "6and4" then
jsonreq6 = utl.exec("echo /status | nc ::1 9090")
end
jsonreq4 = utl.exec("echo /status | nc 127.0.0.1 9090")
jsonreq6 = utl.exec("echo /status | nc ::1 9090")
http.prepare_content("application/json")
if not jsonreq4 or jsonreq4 == "" then
jsonreq4 = "{}"
@ -394,12 +361,8 @@ function fetch_jsoninfo(otable)
local IpVersion = uci:get_first("olsrd", "olsrd","IpVersion")
local jsonreq4 = ""
local jsonreq6 = ""
if IpVersion == "4" or IpVersion == "6and4" then
jsonreq4 = utl.exec("echo /" .. otable .. " | nc 127.0.0.1 9090")
end
if IpVersion == "6" or IpVersion == "6and4" then
jsonreq6 = utl.exec("echo /" .. otable .. " | nc ::1 9090")
end
jsonreq4 = utl.exec("echo /" .. otable .. " | nc 127.0.0.1 9090")
jsonreq6 = utl.exec("echo /" .. otable .. " | nc ::1 9090")
local jsondata4 = {}
local jsondata6 = {}
local data4 = {}

View file

@ -0,0 +1,47 @@
module("luci.controller.olsr4", package.seeall)
function index()
if not nixio.fs.access("/etc/config/olsrd") then
return
end
require("luci.model.uci")
local uci = luci.model.uci.cursor_state()
local ol = entry(
{"admin", "services", "olsrd"},
cbi("olsr/olsrd"), "OLSR IPv4"
)
ol.subindex = true
entry(
{"admin", "services", "olsrd", "iface"},
cbi("olsr/olsrdiface")
).leaf = true
entry(
{"admin", "services", "olsrd", "hna"},
cbi("olsr/olsrdhna"), _("HNA Announcements")
)
oplg = entry(
{"admin", "services", "olsrd", "plugins"},
cbi("olsr/olsrdplugins"), _("Plugins")
)
oplg.leaf = true
oplg.subindex = true
local uci = require("luci.model.uci").cursor()
uci:foreach("olsrd", "LoadPlugin",
function (section)
local lib = section.library
entry(
{"admin", "services", "olsrd", "plugins", lib },
cbi("olsr/olsrdplugins"),
nil --'Plugin "%s"' % lib:gsub("^olsrd_",""):gsub("%.so.+$","")
)
end
)
end

View file

@ -0,0 +1,47 @@
module("luci.controller.olsr6", package.seeall)
function index()
if not nixio.fs.access("/etc/config/olsrd6") then
return
end
require("luci.model.uci")
local uci = luci.model.uci.cursor_state()
local ol = entry(
{"admin", "services", "olsrd6"},
cbi("olsr/olsrd6"), "OLSR IPv6"
)
ol.subindex = true
entry(
{"admin", "services", "olsrd6", "iface"},
cbi("olsr/olsrdiface6")
).leaf = true
entry(
{"admin", "services", "olsrd6", "hna"},
cbi("olsr/olsrdhna6"), _("HNA6 Announcements")
)
oplg = entry(
{"admin", "services", "olsrd6", "plugins"},
cbi("olsr/olsrdplugins6"), _("Plugins")
)
oplg.leaf = true
oplg.subindex = true
local uci = require("luci.model.uci").cursor()
uci:foreach("olsrd6", "LoadPlugin",
function (section)
local lib = section.library
entry(
{"admin", "services", "olsrd6", "plugins", lib },
cbi("olsr/olsrdplugins6"),
nil --'Plugin "%s"' % lib:gsub("^olsrd_",""):gsub("%.so.+$","")
)
end
)
end

View file

@ -58,7 +58,6 @@ s:tab("advanced", translate("Advanced Settings"))
ipv = s:taboption("general", ListValue, "IpVersion", translate("Internet protocol"),
translate("IP-version to use. If 6and4 is selected then one olsrd instance is started for each protocol."))
ipv:value("4", "IPv4")
ipv:value("6", "IPv6")
ipv:value("6and4", "6and4")

View file

@ -0,0 +1,401 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2010 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require("luci.tools.webadmin")
local fs = require "nixio.fs"
local util = require "luci.util"
local ip = require "luci.ip"
local has_ipip = fs.glob("/etc/modules.d/[0-9]*-ipip")()
m = Map("olsrd6", translate("OLSR Daemon"),
translate("The OLSR daemon is an implementation of the Optimized Link State Routing protocol. "..
"As such it allows mesh routing for any network equipment. "..
"It runs on any wifi card that supports ad-hoc mode and of course on any ethernet device. "..
"Visit <a href='http://www.olsr.org'>olsrd.org</a> for help and documentation."))
function m.on_parse()
local has_defaults = false
m.uci:foreach("olsrd6", "InterfaceDefaults",
function(s)
has_defaults = true
return false
end)
if not has_defaults then
m.uci:section("olsrd6", "InterfaceDefaults")
end
end
function write_float(self, section, value)
local n = tonumber(value)
if n ~= nil then
return Value.write(self, section, "%.1f" % n)
end
end
s = m:section(TypedSection, "olsrd6", translate("General settings"))
s.anonymous = true
s:tab("general", translate("General Settings"))
s:tab("lquality", translate("Link Quality Settings"))
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."))
s:tab("advanced", translate("Advanced Settings"))
poll = s:taboption("advanced", Value, "Pollrate", translate("Pollrate"),
translate("Polling rate for OLSR sockets in seconds. Default is 0.05."))
poll.optional = true
poll.datatype = "ufloat"
poll.placeholder = "0.05"
nicc = s:taboption("advanced", Value, "NicChgsPollInt", translate("Nic changes poll interval"),
translate("Interval to poll network interfaces for configuration changes (in seconds). Default is \"2.5\"."))
nicc.optional = true
nicc.datatype = "ufloat"
nicc.placeholder = "2.5"
tos = s:taboption("advanced", Value, "TosValue", translate("TOS value"),
translate("Type of service value for the IP header of control traffic. Default is \"16\"."))
tos.optional = true
tos.datatype = "uinteger"
tos.placeholder = "16"
fib = s:taboption("general", ListValue, "FIBMetric", translate("FIB metric"),
translate ("FIBMetric controls the metric value of the host-routes OLSRd sets. "..
"\"flat\" means that the metric value is always 2. This is the preferred value "..
"because it helps the linux kernel routing to clean up older routes. "..
"\"correct\" uses the hopcount as the metric value. "..
"\"approx\" use the hopcount as the metric value too, but does only update the hopcount if the nexthop changes too. "..
"Default is \"flat\"."))
fib:value("flat")
fib:value("correct")
fib:value("approx")
lql = s:taboption("lquality", ListValue, "LinkQualityLevel", translate("LQ level"),
translate("Link quality level switch between hopcount and cost-based (mostly ETX) routing.<br />"..
"<b>0</b> = do not use link quality<br />"..
"<b>2</b> = use link quality for MPR selection and routing<br />"..
"Default is \"2\""))
lql:value("2")
lql:value("0")
lqage = s:taboption("lquality", Value, "LinkQualityAging", translate("LQ aging"),
translate("Link quality aging factor (only for lq level 2). Tuning parameter for etx_float and etx_fpm, smaller values "..
"mean slower changes of ETX value. (allowed values are between 0.01 and 1.0)"))
lqage.optional = true
lqage:depends("LinkQualityLevel", "2")
lqa = s:taboption("lquality", ListValue, "LinkQualityAlgorithm", translate("LQ algorithm"),
translate("Link quality algorithm (only for lq level 2).<br />"..
"<b>etx_float</b>: floating point ETX with exponential aging<br />"..
"<b>etx_fpm</b> : same as etx_float, but with integer arithmetic<br />"..
"<b>etx_ff</b> : ETX freifunk, an etx variant which use all OLSR traffic (instead of only hellos) for ETX calculation<br />"..
"<b>etx_ffeth</b>: incompatible variant of etx_ff that allows ethernet links with ETX 0.1.<br />"..
"Defaults to \"etx_ff\""))
lqa.optional = true
lqa:value("etx_ff")
lqa:value("etx_fpm")
lqa:value("etx_float")
lqa:value("etx_ffeth")
lqa:depends("LinkQualityLevel", "2")
lqa.optional = true
lqfish = s:taboption("lquality", Flag, "LinkQualityFishEye", translate("LQ fisheye"),
translate("Fisheye mechanism for TCs (checked means on). Default is \"on\""))
lqfish.default = "1"
lqfish.optional = true
hyst = s:taboption("lquality", Flag, "UseHysteresis", translate("Use hysteresis"),
translate("Hysteresis for link sensing (only for hopcount metric). Hysteresis adds more robustness to the link sensing "..
"but delays neighbor registration. Defaults is \"yes\""))
hyst.default = "yes"
hyst.enabled = "yes"
hyst.disabled = "no"
hyst:depends("LinkQualityLevel", "0")
hyst.optional = true
hyst.rmempty = true
port = s:taboption("general", Value, "OlsrPort", translate("Port"),
translate("The port OLSR uses. This should usually stay at the IANA assigned port 698. It can have a value between 1 and 65535."))
port.optional = true
port.default = "698"
port.rmempty = true
mainip = s:taboption("general", Value, "MainIp", translate("Main IP"),
translate("Sets the main IP (originator ip) of the router. This IP will NEVER change during the uptime of olsrd. "..
"Default is ::, which triggers usage of the IP of the first interface."))
mainip.optional = true
mainip.rmempty = true
mainip.datatype = "ipaddr"
mainip.placeholder = "::"
sgw = s:taboption("smartgw", Flag, "SmartGateway", translate("Enable"), translate("Enable SmartGateway. If it is disabled, then " ..
"all other SmartGateway parameters are ignored. Default is \"no\"."))
sgw.default="no"
sgw.enabled="yes"
sgw.disabled="no"
sgw.rmempty = true
sgwnat = s:taboption("smartgw", Flag, "SmartGatewayAllowNAT", translate("Allow gateways with NAT"), translate("Allow the selection of an outgoing ipv4 gateway with NAT"))
sgwnat:depends("SmartGateway", "yes")
sgwnat.default="yes"
sgwnat.enabled="yes"
sgwnat.disabled="no"
sgwnat.optional = true
sgwnat.rmempty = true
sgwuplink = s:taboption("smartgw", ListValue, "SmartGatewayUplink", translate("Announce uplink"), translate("Which kind of uplink is exported to the other mesh nodes. " ..
"An uplink is detected by looking for a local HNA6 ::ffff:0:0/96 or 2000::/3. Default setting is \"both\"."))
sgwuplink:value("none")
sgwuplink:value("ipv4")
sgwuplink:value("ipv6")
sgwuplink:value("both")
sgwuplink:depends("SmartGateway", "yes")
sgwuplink.default="both"
sgwuplink.optional = true
sgwuplink.rmempty = true
sgwulnat = s:taboption("smartgw", Flag, "SmartGatewayUplinkNAT", translate("Uplink uses NAT"), translate("If this Node uses NAT for connections to the internet. " ..
"Default is \"yes\"."))
sgwulnat:depends("SmartGatewayUplink", "ipv4")
sgwulnat:depends("SmartGatewayUplink", "both")
sgwulnat.default="yes"
sgwulnat.enabled="yes"
sgwulnat.disabled="no"
sgwnat.optional = true
sgwnat.rmempty = true
sgwspeed = s:taboption("smartgw", Value, "SmartGatewaySpeed", translate("Speed of the uplink"), translate("Specifies the speed of "..
"the uplink in kilobits/s. First parameter is upstream, second parameter is downstream. Default is \"128 1024\"."))
sgwspeed:depends("SmartGatewayUplink", "ipv4")
sgwspeed:depends("SmartGatewayUplink", "ipv6")
sgwspeed:depends("SmartGatewayUplink", "both")
sgwspeed.optional = true
sgwspeed.rmempty = true
sgwprefix = s:taboption("smartgw", Value, "SmartGatewayPrefix", translate("IPv6-Prefix of the uplink"), translate("This can be used " ..
"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 " ..
"use the IPv6 gateway without any kind of address translation. The maximum prefix length is 64 bits. " ..
"Default is \"::/0\" (no prefix)."))
sgwprefix:depends("SmartGatewayUplink", "ipv6")
sgwprefix:depends("SmartGatewayUplink", "both")
sgwprefix.optional = true
sgwprefix.rmempty = true
willingness = s:taboption("advanced", ListValue, "Willingness", translate("Willingness"),
translate("The fixed willingness to use. If not set willingness will be calculated dynamically based on battery/power status. Default is \"3\"."))
for i=0,7 do
willingness:value(i)
end
willingness.optional = true
willingness.default = "3"
natthr = s:taboption("advanced", Value, "NatThreshold", translate("NAT threshold"),
translate("If the route to the current gateway is to be changed, the ETX value of this gateway is "..
"multiplied with this value before it is compared to the new one. "..
"The parameter can be a value between 0.1 and 1.0, but should be close to 1.0 if changed.<br />"..
"<b>WARNING:</b> This parameter should not be used together with the etx_ffeth metric!<br />"..
"Defaults to \"1.0\"."))
for i=1,0.1,-0.1 do
natthr:value(i)
end
natthr:depends("LinkQualityAlgorithm", "etx_ff")
natthr:depends("LinkQualityAlgorithm", "etx_float")
natthr:depends("LinkQualityAlgorithm", "etx_fpm")
natthr.default = "1.0"
natthr.optional = true
natthr.write = write_float
i = m:section(TypedSection, "InterfaceDefaults", translate("Interfaces Defaults"))
i.anonymous = true
i.addremove = false
i:tab("general", translate("General Settings"))
i:tab("addrs", translate("IP Addresses"))
i:tab("timing", translate("Timing and Validity"))
mode = i:taboption("general", ListValue, "Mode", translate("Mode"),
translate("Interface Mode is used to prevent unnecessary packet forwarding on switched ethernet interfaces. "..
"valid Modes are \"mesh\" and \"ether\". Default is \"mesh\"."))
mode:value("mesh")
mode:value("ether")
mode.optional = true
mode.rmempty = true
weight = i:taboption("general", Value, "Weight", translate("Weight"),
translate("When multiple links exist between hosts the weight of interface is used to determine the link to use. "..
"Normally the weight is automatically calculated by olsrd based on the characteristics of the interface, "..
"but here you can specify a fixed value. Olsrd will choose links with the lowest value.<br />"..
"<b>Note:</b> Interface weight is used only when LinkQualityLevel is set to 0. "..
"For any other value of LinkQualityLevel, the interface ETX value is used instead."))
weight.optional = true
weight.datatype = "uinteger"
weight.placeholder = "0"
lqmult = i:taboption("general", DynamicList, "LinkQualityMult", translate("LinkQuality Multiplicator"),
translate("Multiply routes with the factor given here. Allowed values are between 0.01 and 1.0. "..
"It is only used when LQ-Level is greater than 0. Examples:<br />"..
"reduce LQ to fd91:662e:3c58::1 by half: fd91:662e:3c58::1 0.5<br />"..
"reduce LQ to all nodes on this interface by 20%: default 0.8"))
lqmult.optional = true
lqmult.rmempty = true
lqmult.cast = "table"
lqmult.placeholder = "default 1.0"
function lqmult.validate(self, value)
for _, v in pairs(value) do
if v ~= "" then
local val = util.split(v, " ")
local host = val[1]
local mult = val[2]
if not host or not mult then
return nil, translate("LQMult requires two values (IP address or 'default' and multiplicator) seperated by space.")
end
if not (host == "default" or ip.IPv6(host)) then
return nil, translate("Can only be a valid IPv6 address or 'default'")
end
if not tonumber(mult) or tonumber(mult) > 1 or tonumber(mult) < 0.01 then
return nil, translate("Invalid Value for LQMult-Value. Must be between 0.01 and 1.0.")
end
if not mult:match("[0-1]%.[0-9]+") then
return nil, translate("Invalid Value for LQMult-Value. You must use a decimal number between 0.01 and 1.0 here.")
end
end
end
return value
end
ip6m = i:taboption("addrs", Value, "IPv6Multicast", translate("IPv6 multicast"),
translate("IPv6 multicast address. Default is \"FF02::6D\", the manet-router linklocal multicast."))
ip6m.optional = true
ip6m.datatype = "ip6addr"
ip6m.placeholder = "FF02::6D"
ip6s = i:taboption("addrs", Value, "IPv6Src", translate("IPv6 source"),
translate("IPv6 src prefix. OLSRd will choose one of the interface IPs which matches the prefix of this parameter. "..
"Default is \"0::/0\", which triggers the usage of a not-linklocal interface IP."))
ip6s.optional = true
ip6s.datatype = "ip6addr"
ip6s.placeholder = "0::/0"
hi = i:taboption("timing", Value, "HelloInterval", translate("Hello interval"))
hi.optional = true
hi.datatype = "ufloat"
hi.placeholder = "5.0"
hi.write = write_float
hv = i:taboption("timing", Value, "HelloValidityTime", translate("Hello validity time"))
hv.optional = true
hv.datatype = "ufloat"
hv.placeholder = "40.0"
hv.write = write_float
ti = i:taboption("timing", Value, "TcInterval", translate("TC interval"))
ti.optional = true
ti.datatype = "ufloat"
ti.placeholder = "2.0"
ti.write = write_float
tv = i:taboption("timing", Value, "TcValidityTime", translate("TC validity time"))
tv.optional = true
tv.datatype = "ufloat"
tv.placeholder = "256.0"
tv.write = write_float
mi = i:taboption("timing", Value, "MidInterval", translate("MID interval"))
mi.optional = true
mi.datatype = "ufloat"
mi.placeholder = "18.0"
mi.write = write_float
mv = i:taboption("timing", Value, "MidValidityTime", translate("MID validity time"))
mv.optional = true
mv.datatype = "ufloat"
mv.placeholder = "324.0"
mv.write = write_float
ai = i:taboption("timing", Value, "HnaInterval", translate("HNA interval"))
ai.optional = true
ai.datatype = "ufloat"
ai.placeholder = "18.0"
ai.write = write_float
av = i:taboption("timing", Value, "HnaValidityTime", translate("HNA validity time"))
av.optional = true
av.datatype = "ufloat"
av.placeholder = "108.0"
av.write = write_float
ifs = m:section(TypedSection, "Interface", translate("Interfaces"))
ifs.addremove = true
ifs.anonymous = true
ifs.extedit = luci.dispatcher.build_url("admin/services/olsrd6/iface/%s")
ifs.template = "cbi/tblsection"
function ifs.create(...)
local sid = TypedSection.create(...)
luci.http.redirect(ifs.extedit % sid)
end
ign = ifs:option(Flag, "ignore", translate("Enable"))
ign.enabled = "0"
ign.disabled = "1"
ign.rmempty = false
function ign.cfgvalue(self, section)
return Flag.cfgvalue(self, section) or "0"
end
network = ifs:option(DummyValue, "interface", translate("Network"))
network.template = "cbi/network_netinfo"
mode = ifs:option(DummyValue, "Mode", translate("Mode"))
function mode.cfgvalue(...)
return Value.cfgvalue(...) or m.uci:get_first("olsrd6", "InterfaceDefaults", "Mode", "mesh")
end
hello = ifs:option(DummyValue, "_hello", translate("Hello"))
function hello.cfgvalue(self, section)
local i = tonumber(m.uci:get("olsrd6", section, "HelloInterval")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "HelloInterval", 5))
local v = tonumber(m.uci:get("olsrd6", section, "HelloValidityTime")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "HelloValidityTime", 40))
return "%.01fs / %.01fs" %{ i, v }
end
tc = ifs:option(DummyValue, "_tc", translate("TC"))
function tc.cfgvalue(self, section)
local i = tonumber(m.uci:get("olsrd6", section, "TcInterval")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "TcInterval", 2))
local v = tonumber(m.uci:get("olsrd6", section, "TcValidityTime")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "TcValidityTime", 256))
return "%.01fs / %.01fs" %{ i, v }
end
mid = ifs:option(DummyValue, "_mid", translate("MID"))
function mid.cfgvalue(self, section)
local i = tonumber(m.uci:get("olsrd6", section, "MidInterval")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "MidInterval", 18))
local v = tonumber(m.uci:get("olsrd6", section, "MidValidityTime")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "MidValidityTime", 324))
return "%.01fs / %.01fs" %{ i, v }
end
hna = ifs:option(DummyValue, "_hna", translate("HNA"))
function hna.cfgvalue(self, section)
local i = tonumber(m.uci:get("olsrd6", section, "HnaInterval")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "HnaInterval", 18))
local v = tonumber(m.uci:get("olsrd6", section, "HnaValidityTime")) or tonumber(m.uci:get_first("olsrd6", "InterfaceDefaults", "HnaValidityTime", 108))
return "%.01fs / %.01fs" %{ i, v }
end
return m

View file

@ -0,0 +1,36 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local uci = require "luci.model.uci".cursor()
mh = Map("olsrd6", translate("OLSR - HNA6-Announcements"), translate("Hosts in a OLSR routed network can announce connecitivity " ..
"to external networks using HNA6 messages."))
hna6 = mh:section(TypedSection, "Hna6", translate("Hna6"), translate("IPv6 network must be given in full notation, " ..
"prefix must be in CIDR notation."))
hna6.addremove = true
hna6.anonymous = true
hna6.template = "cbi/tblsection"
net6 = hna6:option(Value, "netaddr", translate("Network address"))
net6.datatype = "ip6addr"
net6.placeholder = "fec0:2200:106:0:0:0:0:0"
net6.default = "fec0:2200:106:0:0:0:0:0"
msk6 = hna6:option(Value, "prefix", translate("Prefix"))
msk6.datatype = "range(0,128)"
msk6.placeholder = "128"
msk6.default = "128"
return mh

View file

@ -0,0 +1,176 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2010 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local util = require "luci.util"
local ip = require "luci.ip"
function write_float(self, section, value)
local n = tonumber(value)
if n ~= nil then
return Value.write(self, section, "%.1f" % n)
end
end
m = Map("olsrd6", translate("OLSR Daemon - Interface"),
translate("The OLSR daemon is an implementation of the Optimized Link State Routing protocol. "..
"As such it allows mesh routing for any network equipment. "..
"It runs on any wifi card that supports ad-hoc mode and of course on any ethernet device. "..
"Visit <a href='http://www.olsr.org'>olsrd.org</a> for help and documentation."))
m.redirect = luci.dispatcher.build_url("admin/services/olsrd6")
if not arg[1] or m.uci:get("olsrd6", arg[1]) ~= "Interface" then
luci.http.redirect(m.redirect)
return
end
i = m:section(NamedSection, arg[1], "Interface", translate("Interface"))
i.anonymous = true
i.addremove = false
i:tab("general", translate("General Settings"))
i:tab("addrs", translate("IP Addresses"))
i:tab("timing", translate("Timing and Validity"))
ign = i:taboption("general", Flag, "ignore", translate("Enable"),
translate("Enable this interface."))
ign.enabled = "0"
ign.disabled = "1"
ign.rmempty = false
function ign.cfgvalue(self, section)
return Flag.cfgvalue(self, section) or "0"
end
network = i:taboption("general", Value, "interface", translate("Network"),
translate("The interface OLSRd should serve."))
network.template = "cbi/network_netlist"
network.widget = "radio"
network.nocreate = true
mode = i:taboption("general", ListValue, "Mode", translate("Mode"),
translate("Interface Mode is used to prevent unnecessary packet forwarding on switched ethernet interfaces. "..
"valid Modes are \"mesh\" and \"ether\". Default is \"mesh\"."))
mode:value("mesh")
mode:value("ether")
mode.optional = true
mode.rmempty = true
weight = i:taboption("general", Value, "Weight", translate("Weight"),
translate("When multiple links exist between hosts the weight of interface is used to determine the link to use. "..
"Normally the weight is automatically calculated by olsrd based on the characteristics of the interface, "..
"but here you can specify a fixed value. Olsrd will choose links with the lowest value.<br />"..
"<b>Note:</b> Interface weight is used only when LinkQualityLevel is set to 0. "..
"For any other value of LinkQualityLevel, the interface ETX value is used instead."))
weight.optional = true
weight.datatype = "uinteger"
weight.placeholder = "0"
lqmult = i:taboption("general", DynamicList, "LinkQualityMult", translate("LinkQuality Multiplicator"),
translate("Multiply routes with the factor given here. Allowed values are between 0.01 and 1.0. "..
"It is only used when LQ-Level is greater than 0. Examples:<br />"..
"reduce LQ to fd91:662e:3c58::1 by half: fd91:662e:3c58::1 0.5<br />"..
"reduce LQ to all nodes on this interface by 20%: default 0.8"))
lqmult.optional = true
lqmult.rmempty = true
lqmult.cast = "table"
lqmult.placeholder = "default 1.0"
function lqmult.validate(self, value)
for _, v in pairs(value) do
if v ~= "" then
local val = util.split(v, " ")
local host = val[1]
local mult = val[2]
if not host or not mult then
return nil, translate("LQMult requires two values (IP address or 'default' and multiplicator) seperated by space.")
end
if not (host == "default" or ip.IPv6(host)) then
return nil, translate("Can only be a valid IPv6 address or 'default'")
end
if not tonumber(mult) or tonumber(mult) > 1 or tonumber(mult) < 0.01 then
return nil, translate("Invalid Value for LQMult-Value. Must be between 0.01 and 1.0.")
end
if not mult:match("[0-1]%.[0-9]+") then
return nil, translate("Invalid Value for LQMult-Value. You must use a decimal number between 0.01 and 1.0 here.")
end
end
end
return value
end
ip6m = i:taboption("addrs", Value, "IPv6Multicast", translate("IPv6 multicast"),
translate("IPv6 multicast address. Default is \"FF02::6D\", the manet-router linklocal multicast."))
ip6m.optional = true
ip6m.datatype = "ip6addr"
ip6m.placeholder = "FF02::6D"
ip6s = i:taboption("addrs", Value, "IPv6Src", translate("IPv6 source"),
translate("IPv6 src prefix. OLSRd will choose one of the interface IPs which matches the prefix of this parameter. "..
"Default is \"0::/0\", which triggers the usage of a not-linklocal interface IP."))
ip6s.optional = true
ip6s.datatype = "ip6addr"
ip6s.placeholder = "0::/0"
hi = i:taboption("timing", Value, "HelloInterval", translate("Hello interval"))
hi.optional = true
hi.datatype = "ufloat"
hi.placeholder = "5.0"
hi.write = write_float
hv = i:taboption("timing", Value, "HelloValidityTime", translate("Hello validity time"))
hv.optional = true
hv.datatype = "ufloat"
hv.placeholder = "40.0"
hv.write = write_float
ti = i:taboption("timing", Value, "TcInterval", translate("TC interval"))
ti.optional = true
ti.datatype = "ufloat"
ti.placeholder = "2.0"
ti.write = write_float
tv = i:taboption("timing", Value, "TcValidityTime", translate("TC validity time"))
tv.optional = true
tv.datatype = "ufloat"
tv.placeholder = "256.0"
tv.write = write_float
mi = i:taboption("timing", Value, "MidInterval", translate("MID interval"))
mi.optional = true
mi.datatype = "ufloat"
mi.placeholder = "18.0"
mi.write = write_float
mv = i:taboption("timing", Value, "MidValidityTime", translate("MID validity time"))
mv.optional = true
mv.datatype = "ufloat"
mv.placeholder = "324.0"
mv.write = write_float
ai = i:taboption("timing", Value, "HnaInterval", translate("HNA interval"))
ai.optional = true
ai.datatype = "ufloat"
ai.placeholder = "18.0"
ai.write = write_float
av = i:taboption("timing", Value, "HnaValidityTime", translate("HNA validity time"))
av.optional = true
av.datatype = "ufloat"
av.placeholder = "108.0"
av.write = write_float
return m

View file

@ -0,0 +1,270 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local ip = require "luci.ip"
local fs = require "nixio.fs"
if arg[1] then
mp = Map("olsrd", translate("OLSR - Plugins"))
p = mp:section(TypedSection, "LoadPlugin", translate("Plugin configuration"))
p:depends("library", arg[1])
p.anonymous = true
ign = p:option(Flag, "ignore", translate("Enable"))
ign.enabled = "0"
ign.disabled = "1"
ign.rmempty = false
function ign.cfgvalue(self, section)
return Flag.cfgvalue(self, section) or "0"
end
lib = p:option(DummyValue, "library", translate("Library"))
lib.default = arg[1]
local function Range(x,y)
local t = {}
for i = x, y do t[#t+1] = i end
return t
end
local function Cidr2IpMask(val)
if val then
for i = 1, #val do
local cidr = ip.IPv4(val[i]) or ip.IPv6(val[i])
if cidr then
val[i] = cidr:network():string() .. " " .. cidr:mask():string()
end
end
return val
end
end
local function IpMask2Cidr(val)
if val then
for i = 1, #val do
local ip, mask = val[i]:gmatch("([^%s]+)%s+([^%s]+)")()
local cidr
if ip and mask and ip:match(":") then
cidr = ip.IPv6(ip, mask)
elseif ip and mask then
cidr = ip.IPv4(ip, mask)
end
if cidr then
val[i] = cidr:string()
end
end
return val
end
end
local knownPlParams = {
["olsrd_bmf.so.1.5.3"] = {
{ Value, "BmfInterface", "bmf0" },
{ Value, "BmfInterfaceIp", "10.10.10.234/24" },
{ Flag, "DoLocalBroadcast", "no" },
{ Flag, "CapturePacketsOnOlsrInterfaces", "yes" },
{ ListValue, "BmfMechanism", { "UnicastPromiscuous", "Broadcast" } },
{ Value, "BroadcastRetransmitCount", "2" },
{ Value, "FanOutLimit", "4" },
{ DynamicList, "NonOlsrIf", "br-lan" }
},
["olsrd_dyn_gw.so.0.4"] = {
{ Value, "Interval", "40" },
{ DynamicList, "Ping", "141.1.1.1" },
{ DynamicList, "HNA", "192.168.80.0/24", IpMask2Cidr, Cidr2IpMask }
},
["olsrd_httpinfo.so.0.1"] = {
{ Value, "port", "80" },
{ DynamicList, "Host", "163.24.87.3" },
{ DynamicList, "Net", "0.0.0.0/0", Cidr2IpMask }
},
["olsrd_nameservice.so.0.3"] = {
{ DynamicList, "name", "my-name.mesh" },
{ DynamicList, "hosts", "1.2.3.4 name-for-other-interface.mesh" },
{ Value, "suffix", ".olsr" },
{ Value, "hosts_file", "/path/to/hosts_file" },
{ Value, "add_hosts", "/path/to/file" },
{ Value, "dns_server", "141.1.1.1" },
{ Value, "resolv_file", "/path/to/resolv.conf" },
{ Value, "interval", "120" },
{ Value, "timeout", "240" },
{ Value, "lat", "12.123" },
{ Value, "lon", "12.123" },
{ Value, "latlon_file", "/var/run/latlon.js.ipv6" },
{ Value, "latlon_infile", "/var/run/gps.txt" },
{ Value, "sighup_pid_file", "/var/run/dnsmasq.pid" },
{ Value, "name_change_script", "/usr/local/bin/announce_new_hosts.sh" },
{ DynamicList, "service", "http://me.olsr:80|tcp|my little homepage" },
{ Value, "services_file", "/var/run/services_olsr" },
{ Value, "services_change_script", "/usr/local/bin/announce_new_services.sh" },
{ DynamicList, "mac", "xx:xx:xx:xx:xx:xx[,0-255]" },
{ Value, "macs_file", "/path/to/macs_file" },
{ Value, "macs_change_script", "/path/to/script" }
},
["olsrd_quagga.so.0.2.2"] = {
{ StaticList, "redistribute", {
"system", "kernel", "connect", "static", "rip", "ripng", "ospf",
"ospf6", "isis", "bgp", "hsls"
} },
{ ListValue, "ExportRoutes", { "only", "both" } },
{ Flag, "LocalPref", "true" },
{ Value, "Distance", Range(0,255) }
},
["olsrd_secure.so.0.5"] = {
{ Value, "Keyfile", "/etc/private-olsr.key" }
},
["olsrd_txtinfo.so.0.1"] = {
{ Value, "accept", "::1/128" }
},
["olsrd_jsoninfo.so.0.0"] = {
{ Value, "accept", "::1/128" },
{ Value, "port", "9090" },
{ Value, "UUIDFile", "/etc/olsrd/olsrd.uuid.ipv6" },
},
["olsrd_watchdog.so.0.1"] = {
{ Value, "file", "/var/run/olsrd.watchdog.ipv6" },
{ Value, "interval", "30" }
},
["olsrd_mdns.so.1.0.0"] = {
{ DynamicList, "NonOlsrIf", "lan" }
},
["olsrd_p2pd.so.0.1.0"] = {
{ DynamicList, "NonOlsrIf", "lan" },
{ Value, "P2pdTtl", "10" }
},
["olsrd_arprefresh.so.0.1"] = {},
["olsrd_dot_draw.so.0.3"] = {},
["olsrd_dyn_gw_plain.so.0.4"] = {},
["olsrd_pgraph.so.1.1"] = {},
["olsrd_tas.so.0.1"] = {}
}
-- build plugin options with dependencies
if knownPlParams[arg[1]] then
for _, option in ipairs(knownPlParams[arg[1]]) do
local otype, name, default, uci2cbi, cbi2uci = unpack(option)
local values
if type(default) == "table" then
values = default
default = default[1]
end
if otype == Flag then
local bool = p:option( Flag, name, name )
if default == "yes" or default == "no" then
bool.enabled = "yes"
bool.disabled = "no"
elseif default == "on" or default == "off" then
bool.enabled = "on"
bool.disabled = "off"
elseif default == "1" or default == "0" then
bool.enabled = "1"
bool.disabled = "0"
else
bool.enabled = "true"
bool.disabled = "false"
end
bool.optional = true
bool.default = default
bool:depends({ library = plugin })
else
local field = p:option( otype, name, name )
if values then
for _, value in ipairs(values) do
field:value( value )
end
end
if type(uci2cbi) == "function" then
function field.cfgvalue(self, section)
return uci2cbi(otype.cfgvalue(self, section))
end
end
if type(cbi2uci) == "function" then
function field.formvalue(self, section)
return cbi2uci(otype.formvalue(self, section))
end
end
field.optional = true
field.default = default
--field:depends({ library = arg[1] })
end
end
end
return mp
else
mpi = Map("olsrd6", translate("OLSR - Plugins"))
local plugins = {}
mpi.uci:foreach("olsrd6", "LoadPlugin",
function(section)
if section.library and not plugins[section.library] then
plugins[section.library] = true
end
end
)
-- create a loadplugin section for each found plugin
for v in fs.dir("/usr/lib") do
if v:sub(1, 6) == "olsrd_" then
if not plugins[v] then
mpi.uci:section(
"olsrd6", "LoadPlugin", nil,
{ library = v, ignore = 1 }
)
end
end
end
t = mpi:section( TypedSection, "LoadPlugin", translate("Plugins") )
t.anonymous = true
t.template = "cbi/tblsection"
t.override_scheme = true
function t.extedit(self, section)
local lib = self.map:get(section, "library") or ""
return luci.dispatcher.build_url("admin", "services", "olsrd6", "plugins") .. "/" .. lib
end
ign = t:option( Flag, "ignore", translate("Enabled") )
ign.enabled = "0"
ign.disabled = "1"
ign.rmempty = false
function ign.cfgvalue(self, section)
return Flag.cfgvalue(self, section) or "0"
end
t:option( DummyValue, "library", translate("Library") )
return mpi
end

View file

@ -4,6 +4,9 @@ uci -q batch <<-EOF >/dev/null
delete ucitrack.@olsrd[-1]
add ucitrack olsrd
set ucitrack.@olsrd[-1].init=olsrd
delete ucitrack.@olsrd6[-1]
add ucitrack olsrd6
set ucitrack.@olsrd6[-1].init=olsrd6
commit ucitrack
EOF