libs/core/ip: optmizations
libs/sys: implement defaultroute6(), change return values of routes() and routes6() modules/admin-full: adept route config page to new api modules/freifunk: adept overview page to new routes api
This commit is contained in:
parent
82f08a4a1d
commit
dda65d2b94
5 changed files with 165 additions and 112 deletions
|
@ -227,7 +227,7 @@ function IPv6(address, netmask)
|
||||||
|
|
||||||
block = tonumber(address:sub(borderl, borderh - 1), 16)
|
block = tonumber(address:sub(borderl, borderh - 1), 16)
|
||||||
if block and block <= 0xFFFF then
|
if block and block <= 0xFFFF then
|
||||||
table.insert(data, block)
|
data[#data+1] = block
|
||||||
else
|
else
|
||||||
if zeroh or borderh - borderl > 1 then return nil end
|
if zeroh or borderh - borderl > 1 then return nil end
|
||||||
zeroh = #data + 1
|
zeroh = #data + 1
|
||||||
|
@ -241,7 +241,7 @@ function IPv6(address, netmask)
|
||||||
block = tonumber(chunk, 16)
|
block = tonumber(chunk, 16)
|
||||||
if not block or block > 0xFFFF then return nil end
|
if not block or block > 0xFFFF then return nil end
|
||||||
|
|
||||||
table.insert(data, block)
|
data[#data+1] = block
|
||||||
elseif #chunk > 4 then
|
elseif #chunk > 4 then
|
||||||
if #data == 7 or #chunk > 15 then return nil end
|
if #data == 7 or #chunk > 15 then return nil end
|
||||||
borderl = 1
|
borderl = 1
|
||||||
|
@ -254,7 +254,7 @@ function IPv6(address, netmask)
|
||||||
if not block or block > 255 then return nil end
|
if not block or block > 255 then return nil end
|
||||||
|
|
||||||
if i == 1 or i == 3 then
|
if i == 1 or i == 3 then
|
||||||
table.insert(data, block * 256)
|
data[#data+1] = block * 256
|
||||||
else
|
else
|
||||||
data[#data] = data[#data] + block
|
data[#data] = data[#data] + block
|
||||||
end
|
end
|
||||||
|
@ -308,7 +308,7 @@ function Hex( hex, prefix, family, swap )
|
||||||
for i = 1, ( len / 4 ), 4 do
|
for i = 1, ( len / 4 ), 4 do
|
||||||
local n = tonumber( hex:sub( i, i+3 ), 16 )
|
local n = tonumber( hex:sub( i, i+3 ), 16 )
|
||||||
if n then
|
if n then
|
||||||
table.insert( data, n )
|
data[#data+1] = n
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
@ -421,26 +421,24 @@ function cidr.prefix( self, mask )
|
||||||
|
|
||||||
if mask then
|
if mask then
|
||||||
prefix = 0
|
prefix = 0
|
||||||
|
|
||||||
local stop = false
|
local stop = false
|
||||||
local obj = self:is4() and IPv4(mask) or IPv6(mask)
|
local obj = type(mask) ~= "table"
|
||||||
|
and ( self:is4() and IPv4(mask) or IPv6(mask) ) or mask
|
||||||
|
|
||||||
if not obj then
|
if not obj then return nil end
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
for i, block in ipairs(obj[2]) do
|
for _, word in ipairs(obj[2]) do
|
||||||
local pos = bit.lshift(1, 15)
|
if word == 0xFFFF then
|
||||||
for i=15, 0, -1 do
|
prefix = prefix + 16
|
||||||
if bit.band(block, pos) == pos then
|
else
|
||||||
if not stop then
|
local bitmask = bit.lshift(1, 15)
|
||||||
|
while bit.band(word, bitmask) == bitmask do
|
||||||
prefix = prefix + 1
|
prefix = prefix + 1
|
||||||
else
|
bitmask = bit.lshift(1, 15 - (prefix % 16))
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
else
|
|
||||||
stop = true
|
break
|
||||||
end
|
|
||||||
pos = bit.rshift(pos, 1)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -460,14 +458,14 @@ function cidr.network( self, bits )
|
||||||
bits = bits or self[3]
|
bits = bits or self[3]
|
||||||
|
|
||||||
for i = 1, math.floor( bits / 16 ) do
|
for i = 1, math.floor( bits / 16 ) do
|
||||||
table.insert( data, self[2][i] )
|
data[#data+1] = self[2][i]
|
||||||
end
|
end
|
||||||
|
|
||||||
if #data < #self[2] then
|
if #data < #self[2] then
|
||||||
table.insert( data, bit.band( self[2][1+#data], __mask16(bits) ) )
|
data[#data+1] = bit.band( self[2][1+#data], __mask16(bits) )
|
||||||
|
|
||||||
for i = #data + 1, #self[2] do
|
for i = #data + 1, #self[2] do
|
||||||
table.insert( data, 0 )
|
data[#data+1] = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -495,14 +493,14 @@ function cidr.mask( self, bits )
|
||||||
bits = bits or self[3]
|
bits = bits or self[3]
|
||||||
|
|
||||||
for i = 1, math.floor( bits / 16 ) do
|
for i = 1, math.floor( bits / 16 ) do
|
||||||
table.insert( data, 0xFFFF )
|
data[#data+1] = 0xFFFF
|
||||||
end
|
end
|
||||||
|
|
||||||
if #data < #self[2] then
|
if #data < #self[2] then
|
||||||
table.insert( data, __mask16(bits) )
|
data[#data+1] = __mask16(bits)
|
||||||
|
|
||||||
for i = #data + 1, #self[2] do
|
for i = #data + 1, #self[2] do
|
||||||
table.insert( data, 0 )
|
data[#data+1] = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -294,21 +294,35 @@ function net.conntrack()
|
||||||
return connt
|
return connt
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Determine the current default route.
|
--- Determine the current IPv4 default route. If multiple default routes exist,
|
||||||
|
-- return the one with the lowest metric.
|
||||||
-- @return Table with the properties of the current default route.
|
-- @return Table with the properties of the current default route.
|
||||||
-- The following fields are defined:
|
-- The following fields are defined:
|
||||||
-- { "Mask", "RefCnt", "Iface", "Flags", "Window", "IRTT",
|
-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
|
||||||
-- "MTU", "Gateway", "Destination", "Metric", "Use" }
|
-- "flags", "device" }
|
||||||
function net.defaultroute()
|
function net.defaultroute()
|
||||||
local routes = net.routes()
|
|
||||||
local route = nil
|
local route = nil
|
||||||
|
for _, r in pairs(net.routes()) do
|
||||||
for i, r in pairs(luci.sys.net.routes()) do
|
if r.dest:prefix() == 0 and (not route or route.metric > r.metric) then
|
||||||
if r.Destination == "00000000" and (not route or route.Metric > r.Metric) then
|
|
||||||
route = r
|
route = r
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return route
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Determine the current IPv6 default route. If multiple default routes exist,
|
||||||
|
-- return the one with the lowest metric.
|
||||||
|
-- @return Table with the properties of the current default route.
|
||||||
|
-- The following fields are defined:
|
||||||
|
-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
|
||||||
|
-- "flags", "device" }
|
||||||
|
function net.defaultroute6()
|
||||||
|
local route = nil
|
||||||
|
for _, r in pairs(net.routes6()) do
|
||||||
|
if r.dest:prefix() == 0 and (not route or route.metric > r.metric) then
|
||||||
|
route = r
|
||||||
|
end
|
||||||
|
end
|
||||||
return route
|
return route
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -355,17 +369,49 @@ end
|
||||||
--- Returns the current kernel routing table entries.
|
--- Returns the current kernel routing table entries.
|
||||||
-- @return Table of tables with properties of the corresponding routes.
|
-- @return Table of tables with properties of the corresponding routes.
|
||||||
-- The following fields are defined for route entry tables:
|
-- The following fields are defined for route entry tables:
|
||||||
-- { "Mask", "RefCnt", "Iface", "Flags", "Window", "IRTT",
|
-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
|
||||||
-- "MTU", "Gateway", "Destination", "Metric", "Use" }
|
-- "flags", "device" }
|
||||||
function net.routes()
|
function net.routes()
|
||||||
return _parse_delimited_table(io.lines("/proc/net/route"))
|
local routes = { }
|
||||||
|
|
||||||
|
for line in io.lines("/proc/net/route") do
|
||||||
|
|
||||||
|
local dev, dst_ip, gateway, flags, refcnt, usecnt, metric,
|
||||||
|
dst_mask, mtu, win, irtt = line:match(
|
||||||
|
"([^%s]+)\t([A-F0-9]+)\t([A-F0-9]+)\t([A-F0-9]+)\t" ..
|
||||||
|
"(%d+)\t(%d+)\t(%d+)\t([A-F0-9]+)\t(%d+)\t(%d+)\t(%d+)"
|
||||||
|
)
|
||||||
|
|
||||||
|
if dev then
|
||||||
|
gateway = luci.ip.Hex( gateway, 32, luci.ip.FAMILY_INET4 )
|
||||||
|
dst_mask = luci.ip.Hex( dst_mask, 32, luci.ip.FAMILY_INET4 )
|
||||||
|
dst_ip = luci.ip.Hex(
|
||||||
|
dst_ip, dst_mask:prefix(dst_mask), luci.ip.FAMILY_INET4
|
||||||
|
)
|
||||||
|
|
||||||
|
routes[#routes+1] = {
|
||||||
|
dest = dst_ip,
|
||||||
|
gateway = gateway,
|
||||||
|
metric = tonumber(metric),
|
||||||
|
refcount = tonumber(refcnt),
|
||||||
|
usecount = tonumber(usecnt),
|
||||||
|
mtu = tonumber(mtu),
|
||||||
|
window = tonumber(window),
|
||||||
|
irtt = tonumber(irtt),
|
||||||
|
flags = tonumber(flags, 16),
|
||||||
|
device = dev
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return routes
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the current ipv6 kernel routing table entries.
|
--- Returns the current ipv6 kernel routing table entries.
|
||||||
-- @return Table of tables with properties of the corresponding routes.
|
-- @return Table of tables with properties of the corresponding routes.
|
||||||
-- The following fields are defined for route entry tables:
|
-- The following fields are defined for route entry tables:
|
||||||
-- { "src_ip", "src_prefix", "dst_ip", "dst_prefix", "nexthop_ip",
|
-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
|
||||||
-- "metric", "refcount", "usecount", "flags", "device" }
|
-- "flags", "device" }
|
||||||
function net.routes6()
|
function net.routes6()
|
||||||
local routes = { }
|
local routes = { }
|
||||||
|
|
||||||
|
@ -377,31 +423,27 @@ function net.routes6()
|
||||||
"([a-f0-9]+) ([a-f0-9]+) " ..
|
"([a-f0-9]+) ([a-f0-9]+) " ..
|
||||||
"([a-f0-9]+) ([a-f0-9]+) " ..
|
"([a-f0-9]+) ([a-f0-9]+) " ..
|
||||||
"([a-f0-9]+) ([a-f0-9]+) " ..
|
"([a-f0-9]+) ([a-f0-9]+) " ..
|
||||||
"([^%s]+) +([^%s]+)"
|
"([a-f0-9]+) +([^%s]+)"
|
||||||
)
|
)
|
||||||
|
|
||||||
src_ip = luci.ip.Hex(
|
src_ip = luci.ip.Hex(
|
||||||
src_ip, tonumber(src_prefix, 16),
|
src_ip, tonumber(src_prefix, 16), luci.ip.FAMILY_INET6, false
|
||||||
luci.ip.FAMILY_INET6, false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
dst_ip = luci.ip.Hex(
|
dst_ip = luci.ip.Hex(
|
||||||
dst_ip, tonumber(dst_prefix, 16),
|
dst_ip, tonumber(dst_prefix, 16), luci.ip.FAMILY_INET6, false
|
||||||
luci.ip.FAMILY_INET6, false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
nexthop = luci.ip.Hex( nexthop, 128, luci.ip.FAMILY_INET6, false )
|
nexthop = luci.ip.Hex( nexthop, 128, luci.ip.FAMILY_INET6, false )
|
||||||
|
|
||||||
routes[#routes+1] = {
|
routes[#routes+1] = {
|
||||||
src_ip = src_ip:host():string(),
|
source = src_ip,
|
||||||
src_prefix = src_ip:prefix(),
|
dest = dst_ip,
|
||||||
dst_ip = dst_ip:host():string(),
|
nexthop = nexthop,
|
||||||
dst_prefix = dst_ip:prefix(),
|
|
||||||
nexthop_ip = nexthop:string(),
|
|
||||||
metric = tonumber(metric, 16),
|
metric = tonumber(metric, 16),
|
||||||
refcount = tonumber(refcnt, 16),
|
refcount = tonumber(refcnt, 16),
|
||||||
usecount = tonumber(usecnt, 16),
|
usecount = tonumber(usecnt, 16),
|
||||||
flags = tonumber(flags), -- hex?
|
flags = tonumber(flags, 16),
|
||||||
device = dev
|
device = dev
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,23 +21,23 @@ if not arg or not arg[1] then
|
||||||
|
|
||||||
net = v:option(DummyValue, "iface", translate("network"))
|
net = v:option(DummyValue, "iface", translate("network"))
|
||||||
function net.cfgvalue(self, section)
|
function net.cfgvalue(self, section)
|
||||||
return luci.tools.webadmin.iface_get_network(routes[section].Iface)
|
return luci.tools.webadmin.iface_get_network(routes[section].device)
|
||||||
or routes[section].Iface
|
or routes[section].device
|
||||||
end
|
end
|
||||||
|
|
||||||
target = v:option(DummyValue, "target", translate("target"))
|
target = v:option(DummyValue, "target", translate("target"))
|
||||||
function target.cfgvalue(self, section)
|
function target.cfgvalue(self, section)
|
||||||
return luci.ip.Hex(routes[section].Destination, 32):string()
|
return routes[section].dest:network():string()
|
||||||
end
|
end
|
||||||
|
|
||||||
netmask = v:option(DummyValue, "netmask", translate("netmask"))
|
netmask = v:option(DummyValue, "netmask", translate("netmask"))
|
||||||
function netmask.cfgvalue(self, section)
|
function netmask.cfgvalue(self, section)
|
||||||
return luci.ip.Hex(routes[section].Mask, 32):string()
|
return routes[section].dest:mask():string()
|
||||||
end
|
end
|
||||||
|
|
||||||
gateway = v:option(DummyValue, "gateway", translate("gateway"))
|
gateway = v:option(DummyValue, "gateway", translate("gateway"))
|
||||||
function gateway.cfgvalue(self, section)
|
function gateway.cfgvalue(self, section)
|
||||||
return luci.ip.Hex(routes[section].Gateway, 32):string()
|
return routes[section].gateway:string()
|
||||||
end
|
end
|
||||||
|
|
||||||
metric = v:option(DummyValue, "Metric", translate("metric"))
|
metric = v:option(DummyValue, "Metric", translate("metric"))
|
||||||
|
@ -55,12 +55,12 @@ if not arg or not arg[1] then
|
||||||
|
|
||||||
target = v:option(DummyValue, "target", translate("target"))
|
target = v:option(DummyValue, "target", translate("target"))
|
||||||
function target.cfgvalue(self, section)
|
function target.cfgvalue(self, section)
|
||||||
return routes6[section].dst_ip .. "/" .. routes6[section].dst_prefix
|
return routes6[section].dest:string()
|
||||||
end
|
end
|
||||||
|
|
||||||
gateway = v:option(DummyValue, "gateway", translate("gateway6"))
|
gateway = v:option(DummyValue, "gateway", translate("gateway6"))
|
||||||
function gateway.cfgvalue(self, section)
|
function gateway.cfgvalue(self, section)
|
||||||
return routes6[section].src_ip .. "/" .. routes6[section].src_prefix
|
return routes6[section].source:string()
|
||||||
end
|
end
|
||||||
|
|
||||||
metric = v:option(DummyValue, "Metric", translate("metric"))
|
metric = v:option(DummyValue, "Metric", translate("metric"))
|
||||||
|
|
|
@ -68,24 +68,3 @@ function index()
|
||||||
page.title = "Kontakt"
|
page.title = "Kontakt"
|
||||||
page.order = 40
|
page.order = 40
|
||||||
end
|
end
|
||||||
|
|
||||||
function action_status()
|
|
||||||
local data = {}
|
|
||||||
|
|
||||||
data.system, data.model, data.memtotal, data.memcached, data.membuffers, data.memfree = luci.sys.sysinfo()
|
|
||||||
data.perc_memfree = math.floor((data.memfree/data.memtotal)*100)
|
|
||||||
data.perc_membuffers = math.floor((data.membuffers/data.memtotal)*100)
|
|
||||||
data.perc_memcached = math.floor((data.memcached/data.memtotal)*100)
|
|
||||||
|
|
||||||
data.wifi = luci.sys.wifi.getiwconfig()
|
|
||||||
|
|
||||||
data.routes = {}
|
|
||||||
for i, r in pairs(luci.sys.net.routes()) do
|
|
||||||
if r.Destination == "00000000" then
|
|
||||||
table.insert(data.routes, r)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
luci.template.render("public_status/index", data)
|
|
||||||
end
|
|
|
@ -137,9 +137,10 @@ t2:option(DummyValue, "Noise level", translate("iwscan_noise"))
|
||||||
r = SimpleForm("routes", "Standardrouten")
|
r = SimpleForm("routes", "Standardrouten")
|
||||||
r.submit = false
|
r.submit = false
|
||||||
r.reset = false
|
r.reset = false
|
||||||
|
|
||||||
local routes = {}
|
local routes = {}
|
||||||
for i, route in ipairs(luci.sys.net.routes()) do
|
for i, route in ipairs(luci.sys.net.routes()) do
|
||||||
if route.Destination == "00000000" then
|
if route.dest:prefix() == 0 then
|
||||||
routes[#routes+1] = route
|
routes[#routes+1] = route
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -148,26 +149,59 @@ v = r:section(Table, routes)
|
||||||
|
|
||||||
net = v:option(DummyValue, "iface", translate("network"))
|
net = v:option(DummyValue, "iface", translate("network"))
|
||||||
function net.cfgvalue(self, section)
|
function net.cfgvalue(self, section)
|
||||||
return luci.tools.webadmin.iface_get_network(routes[section].Iface)
|
return luci.tools.webadmin.iface_get_network(routes[section].device)
|
||||||
or routes[section].Iface
|
or routes[section].device
|
||||||
end
|
end
|
||||||
|
|
||||||
target = v:option(DummyValue, "target", translate("target"))
|
target = v:option(DummyValue, "target", translate("target"))
|
||||||
function target.cfgvalue(self, section)
|
function target.cfgvalue(self, section)
|
||||||
return luci.ip.Hex(routes[section].Destination, 32):string()
|
return routes[section].dest:network():string()
|
||||||
end
|
end
|
||||||
|
|
||||||
netmask = v:option(DummyValue, "netmask", translate("netmask"))
|
netmask = v:option(DummyValue, "netmask", translate("netmask"))
|
||||||
function netmask.cfgvalue(self, section)
|
function netmask.cfgvalue(self, section)
|
||||||
return luci.ip.Hex(routes[section].Mask, 32):string()
|
return routes[section].dest:mask():string()
|
||||||
end
|
end
|
||||||
|
|
||||||
gateway = v:option(DummyValue, "gateway", translate("gateway"))
|
gateway = v:option(DummyValue, "gateway", translate("gateway"))
|
||||||
function gateway.cfgvalue(self, section)
|
function gateway.cfgvalue(self, section)
|
||||||
return luci.ip.Hex(routes[section].Gateway, 32):string()
|
return routes[section].gateway:string()
|
||||||
end
|
end
|
||||||
|
|
||||||
metric = v:option(DummyValue, "Metric", translate("metric"))
|
metric = v:option(DummyValue, "metric", translate("metric"))
|
||||||
|
function metric.cfgvalue(self, section)
|
||||||
|
return routes[section].metric
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local routes6 = {}
|
||||||
|
for i, route in ipairs(luci.sys.net.routes6()) do
|
||||||
|
if route.dest:prefix() == 0 then
|
||||||
|
routes6[#routes6+1] = route
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
v6 = r:section(Table, routes6)
|
||||||
|
|
||||||
|
net = v6:option(DummyValue, "iface", translate("network"))
|
||||||
|
function net.cfgvalue(self, section)
|
||||||
|
return luci.tools.webadmin.iface_get_network(routes[section].device)
|
||||||
|
or routes6[section].device
|
||||||
|
end
|
||||||
|
|
||||||
|
target = v6:option(DummyValue, "target", translate("target"))
|
||||||
|
function target.cfgvalue(self, section)
|
||||||
|
return routes6[section].dest:string()
|
||||||
|
end
|
||||||
|
|
||||||
|
gateway = v6:option(DummyValue, "gateway6", translate("gateway6"))
|
||||||
|
function gateway.cfgvalue(self, section)
|
||||||
|
return routes6[section].source:string()
|
||||||
|
end
|
||||||
|
|
||||||
|
metric = v6:option(DummyValue, "metric", translate("metric"))
|
||||||
|
function metric.cfgvalue(self, section)
|
||||||
|
return string.format("%X", routes6[section].metric)
|
||||||
|
end
|
||||||
|
|
||||||
return f, m, r
|
return f, m, r
|
||||||
|
|
Loading…
Reference in a new issue