summaryrefslogtreecommitdiffhomepage
path: root/libs
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2010-10-12 05:28:49 +0000
committerJo-Philipp Wich <jow@openwrt.org>2010-10-12 05:28:49 +0000
commit5c2000a1572afd0df74339775dfa8b61e287a53e (patch)
treed6d7648afe87f9c128a497f2590a0399fa9abbb0 /libs
parent2472cd5613cf5dfc5760c084c8094bead7ddb507 (diff)
libs: merge libs/uci into libs/core
Diffstat (limited to 'libs')
-rw-r--r--libs/core/luasrc/model/network.lua895
-rw-r--r--libs/core/luasrc/model/uci.lua (renamed from libs/uci/luasrc/model/uci.lua)0
-rw-r--r--libs/core/luasrc/model/uci/bind.lua (renamed from libs/uci/luasrc/model/uci/bind.lua)0
-rw-r--r--libs/core/root/etc/config/ucitrack (renamed from libs/uci/root/etc/config/ucitrack)0
-rwxr-xr-xlibs/core/root/sbin/luci-reload (renamed from libs/uci/root/sbin/luci-reload)0
5 files changed, 895 insertions, 0 deletions
diff --git a/libs/core/luasrc/model/network.lua b/libs/core/luasrc/model/network.lua
index 8459463f1..53649dde5 100644
--- a/libs/core/luasrc/model/network.lua
+++ b/libs/core/luasrc/model/network.lua
@@ -483,3 +483,898 @@ function interface.get_network(self)
end
end
+--[==[
+#!/usr/bin/lua
+
+local uci = require "luci.model.uci".cursor_state()
+local utl = require "luci.util"
+local sys = require "luci.sys"
+local lip = require "luci.ip"
+local nxo = require "nixio"
+local nfs = require "nixio.fs"
+
+-- patch uci
+local x = getmetatable(uci)
+
+function x:list(...)
+ local val = self:get(...)
+ local lst = { }
+
+ if type(val) == "list" then
+ local _, v
+ for _, v in ipairs(val) do
+ local i
+ for i in v:gmatch("%S+") do
+ lst[#lst+1] = i
+ end
+ end
+ elseif type(val) == "string" then
+ local i
+ for i in val:gmatch("%S+") do
+ lst[#lst+1] = i
+ end
+ end
+
+ return lst
+end
+
+
+system = utl.class()
+
+system._switches = { }
+system._vlans = { }
+
+function system:__init__()
+ self._networks = { }
+
+ uci:foreach("network2", "interface",
+ function(s)
+ self._networks[#self._networks+1] = system.network(s, self)
+ end)
+end
+
+function system:networks()
+ local index = 0
+ return function()
+ if index <= #self._networks then
+ index = index + 1
+ return self._networks[index]
+ else
+ return nil
+ end
+ end
+end
+
+function system:find_network(name)
+ local v
+ for _, v in ipairs(self._networks) do
+ if v:name() == name then
+ return v
+ end
+ end
+end
+
+function system:find_interface(name)
+ local v
+ for _, v in ipairs(self._networks) do
+ local i
+ for i in v:interfaces() do
+ if i:is_bridge() then
+ local p
+ for p in i:interfaces() do
+ if p:name() == name then
+ return p
+ end
+ end
+ end
+
+ if i:name() == name then
+ return i
+ end
+ end
+ end
+end
+
+function system:delete_network(name)
+ local i
+ for i = 1, #self._networks do
+ if self._networks[i]:name() == name then
+ local x
+
+ for x in self._networks[i]:aliases() do
+ uci:delete("network2", x:name())
+ end
+
+ for x in self._networks[i]:routes() do
+ uci:delete("network2", x:name())
+ end
+
+ uci:delete("network2", self._networks[i])
+ table.remove(self._networks, i)
+
+ return true
+ end
+ end
+ return false
+end
+
+function system:print()
+ local v
+ for v in self:networks() do
+ print(v:name())
+ v:print()
+ print("--")
+ end
+end
+
+function system.ignore_iface(ifn)
+ return (nil ~= (
+ ifn:match("^wlan%d") or
+ ifn:match("^ath%d") or
+ ifn:match("^wl%d") or
+ ifn:match("^imq%d") or
+ ifn:match("^br%-") or
+ ifn:match("^/dev/")
+ ))
+end
+
+function system.find_wifi_networks(net)
+ local lst = { }
+ local cnt = 0
+
+ uci:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.device and s.network == net then
+ lst[#lst+1] = { s.device, s['.name'], cnt }
+ end
+ cnt = cnt + 1
+ end)
+
+ return lst
+end
+
+function system.find_iface_names(net)
+ local lst = { }
+
+ local val = uci:list("network2", net, "device")
+ if #val == 0 or val[1]:match("^/dev/") then
+ val = uci:list("network2", net, "ifname")
+ end
+
+ local ifn
+ for _, ifn in ipairs(val) do
+ if not system.ignore_iface(ifn) then
+ lst[#lst+1] = ifn
+ end
+ end
+
+ return lst
+end
+
+function system.find_switch(name)
+ local swname, swdev, swvlan
+
+ -- find switch
+ uci:foreach("network2", "switch",
+ function(s)
+ swname = s.name or s['.name']
+
+ -- special: rtl8366s is eth0 (wan is eth1)
+ if swname == "rtl8366s" then
+ swdev = "eth0"
+
+ -- special: rtl8366rb is eth0 (wan + lan)
+ elseif swname == "rtl8366rb" then
+ swdev = "eth0"
+
+ -- treat swname as swdev
+ else
+ swdev = swname
+ end
+
+ return false
+ end)
+
+ -- find first vlan
+ if swdev then
+ uci:foreach("network2", "switch_vlan",
+ function(s)
+ if s.device == swname then
+ local vlan = tonumber(s.vlan)
+ if vlan and (not swvlan or vlan < swvlan) then
+ swvlan = vlan
+ end
+ end
+ end)
+ end
+
+
+ local veth, vlan = name:match("^(%S+)%.(%d+)$")
+
+ -- have vlan id and matching switch
+ if vlan and veth == swdev then
+ return swname, swdev, vlan
+
+ -- have no vlan id but matching switch, assume first switch vlan
+ elseif not vlan and name == swdev then
+ return swname, swdev, swvlan
+
+ -- have vlan and no matching switch, assume software vlan
+ elseif vlan then
+ return nil, veth, vlan
+ end
+end
+
+
+system.network = utl.class()
+
+function system.network:__init__(s, sys)
+ self._name = s['.name']
+ self._sys = sys
+ self._routes = { }
+ self._aliases = { }
+
+ if s.type == "bridge" then
+ self._interfaces = { system.network.bridge(s['.name'], self) }
+ else
+ self._interfaces = { }
+
+ local ifn
+
+ -- find wired ifaces
+ for _, ifn in ipairs(system.find_iface_names(self._name)) do
+ self._interfaces[#self._interfaces+1] = system.network.iface(ifn, self)
+ end
+
+ -- find wifi networks
+ for _, ifn in ipairs(system.find_wifi_networks(self._name)) do
+ self._interfaces[#self._interfaces+1] = system.network.iface(ifn, self)
+ end
+ end
+
+ -- find ipv4 routes
+ uci:foreach("network2", "route",
+ function(s)
+ if s.interface == self._name and s.target then
+ self._routes[#self._routes+1] = system.network.route(s, self)
+ end
+ end)
+
+ -- find ipv6 routes
+ uci:foreach("network2", "route6",
+ function(s)
+ if s.interface == self._name and s.target then
+ self._routes[#self._routes+1] = system.network.route(s, self)
+ end
+ end)
+
+ -- find aliases
+ uci:foreach("network2", "alias",
+ function(s)
+ if s.interface == self._name and s.proto then
+ self._aliases[#self._aliases+1] = system.network.alias(s, self)
+ end
+ end)
+end
+
+function system.network:name()
+ return self._name
+end
+
+function system.network:system()
+ return self._sys
+end
+
+function system.network:interfaces()
+ local index = 0
+ return function()
+ if index <= #self._interfaces then
+ index = index + 1
+ return self._interfaces[index]
+ else
+ return nil
+ end
+ end
+end
+
+function system.network:interface()
+ return self._interfaces[1]
+end
+
+function system.network:num_routes()
+ return #self._routes
+end
+
+function system.network:routes()
+ local index = 0
+ return function()
+ if index <= #self._routes then
+ index = index + 1
+ return self._routes[index]
+ else
+ return nil
+ end
+ end
+end
+
+function system.network:num_aliases()
+ return #self._aliases
+end
+
+function system.network:aliases()
+ local index = 0
+ return function()
+ if index <= #self._aliases then
+ index = index + 1
+ return self._aliases[index]
+ else
+ return nil
+ end
+ end
+end
+
+function system.network:delete_route(rt)
+ local i
+ for i = 1, #self._routes do
+ if self._routes[i]:name() == rt:name() then
+ uci:delete("network2", rt:name())
+ table.remove(self._routes, i)
+ return true
+ end
+ end
+ return false
+end
+
+function system.network:delete_alias(al)
+ local i
+ for i = 1, #self._aliases do
+ if self._aliases[i]:name() == al:name() then
+ uci:delete("network2", al:name())
+ table.remove(self._aliases, i)
+ return true
+ end
+ end
+ return false
+end
+
+function system.network:print()
+ self:interface():print()
+end
+
+
+system.network.iface = utl.class()
+
+function system.network.iface:__init__(ifn, net, parent)
+ self._net = net
+ self._parent = parent
+
+ -- is a wifi iface
+ if type(ifn) == "table" then
+ local wifidev, network, index = unpack(ifn)
+
+ self._name = "%s.%d" %{ wifidev, index }
+ self._wifidev = wifidev
+ self._wifinet = index
+ self._ifname = uci:get("wireless", network, "ifname") or self._name
+
+ -- is a wired iface
+ else
+ self._name = ifn
+ self._ifname = ifn
+
+ local switch, swdev, vlan = system.find_switch(self._ifname)
+
+ if switch then
+ self._switch = system.switch(switch, swdev, self)
+ end
+
+ if vlan then
+ self._vlan = system.vlan(vlan, self._switch, self)
+ end
+ end
+end
+
+function system.network.iface:name()
+ return self._name
+end
+
+function system.network.iface:parent()
+ return self._parent
+end
+
+function system.network.iface:network()
+ return self._net
+end
+
+function system.network.iface:is_managed()
+ return (self._net ~= nil)
+end
+
+function system.network.iface:is_vlan()
+ return (self._vlan ~= nil)
+end
+
+function system.network.iface:is_software_vlan()
+ return (not self._switch and self._vlan ~= nil)
+end
+
+function system.network.iface:is_hardware_vlan()
+ return (self._switch ~= nil and self._vlan ~= nil)
+end
+
+function system.network.iface:_sysfs(path, default)
+ path = "/sys/class/net/%s/%s" %{ self._ifname, path }
+
+ local data = nfs.readfile(path)
+
+ if type(default) == "number" then
+ return tonumber(data) or default
+ elseif data and #data > 0 then
+ return data and data:gsub("%s+$", "") or default
+ end
+
+ return default
+end
+
+function system.network.iface:rx_bytes()
+ return self:_sysfs("statistics/rx_bytes", 0)
+end
+
+function system.network.iface:tx_bytes()
+ return self:_sysfs("statistics/tx_bytes", 0)
+end
+
+function system.network.iface:rx_packets()
+ return self:_sysfs("statistics/rx_packets", 0)
+end
+
+function system.network.iface:tx_packets()
+ return self:_sysfs("statistics/tx_packets", 0)
+end
+
+function system.network.iface:macaddr()
+ return self:_sysfs("address")
+end
+
+function system.network.iface:mtu()
+ return self:_sysfs("mtu", 1500)
+end
+
+function system.network.iface:is_bridge()
+ return (self:_sysfs("bridge/max_age", 0) > 0)
+end
+
+function system.network.iface:is_bridge_port()
+ return (self:_sysfs("brport/port_no", 0) > 0)
+end
+
+function system.network.iface:delete()
+ if self._wifidev then
+ local cnt = 0
+ uci:foreach("wireless", "wifi-iface",
+ function(s)
+ cnt = cnt + 1
+ if s.device == self._wifidev and cnt == self._wifinet then
+ uci:delete("wireless", s['.name'])
+ return false
+ end
+ end)
+ end
+end
+
+function system.network.iface:print()
+ if self._wifidev then
+ print(" wifi: ", self._wifidev, "net: ", self._wifinet)
+ else
+ print(" iface: ", self._name)
+ end
+
+ print(" rx: ", self:rx_bytes(), self:rx_packets())
+ print(" tx: ", self:tx_bytes(), self:tx_packets())
+ print(" mtu: ", self:mtu())
+ print(" mac: ", self:macaddr())
+ print(" bridge? ", self:is_bridge())
+ print(" port? ", self:is_bridge_port())
+ print(" swvlan? ", self:is_software_vlan())
+ print(" hwvlan? ", self:is_hardware_vlan())
+
+ if self._switch then
+ self._switch:print()
+ end
+
+ if self._vlan then
+ self._vlan:print()
+ end
+end
+
+
+system.network.bridge = utl.class(system.network.iface)
+
+function system.network.bridge:__init__(brn, net)
+ self._net = net
+ self._name = "br-" .. brn
+ self._ifname = self._name
+ self._interfaces = { }
+
+ local ifn
+
+ -- find wired ifaces
+ for _, ifn in ipairs(system.find_iface_names(brn)) do
+ self._interfaces[#self._interfaces+1] = system.network.iface(ifn, net, self)
+ end
+
+ -- find wifi networks
+ for _, ifn in ipairs(system.find_wifi_networks(brn)) do
+ self._interfaces[#self._interfaces+1] = system.network.iface(ifn, net, self)
+ end
+end
+
+function system.network.bridge:interfaces()
+ local index = 0
+ return function()
+ if index <= #self._interfaces then
+ index = index + 1
+ return self._interfaces[index]
+ else
+ return nil
+ end
+ end
+end
+
+function system.network.bridge:print()
+ local v
+ for v in self:interfaces() do
+ io.write(" port: ")
+ v:print()
+ end
+ print(" rx: ", self:rx_bytes(), self:rx_packets())
+ print(" tx: ", self:tx_bytes(), self:tx_packets())
+ print(" mtu: ", self:mtu())
+ print(" mac: ", self:macaddr())
+ print(" bridge? ", self:is_bridge())
+ print(" port? ", self:is_bridge_port())
+end
+
+
+system.network.route = utl.class()
+
+function system.network.route:__init__(rt, net)
+ self._net = net
+ self._name = rt['.name']
+ self._ipv6 = (rt['.type'] == "route6")
+ self._mtu = tonumber(rt.mtu) or (net and net:interface():mtu() or 1500)
+ self._metric = tonumber(rt.metric) or 0
+
+ if self._ipv6 then
+ self._gateway = lip.IPv6(rt.gateway or "::")
+ self._target = lip.IPv6(rt.target or "::")
+ else
+ self._gateway = lip.IPv4(rt.gateway or "0.0.0.0")
+ self._target = lip.IPv4(rt.target or "0.0.0.0", rt.netmask or "0.0.0.0")
+ end
+end
+
+function system.network.route:name()
+ return self._name
+end
+
+function system.network.route:network()
+ return self._net
+end
+
+function system.network.route:mtu()
+ return self._mtu
+end
+
+function system.network.route:metric()
+ return self._metric
+end
+
+function system.network.route:is_ipv4()
+ return not self._ipv6
+end
+
+function system.network.route:is_ipv6()
+ return self._ipv6
+end
+
+function system.network.route:target()
+ return self._target
+end
+
+function system.network.route:gateway()
+ return self._gateway
+end
+
+
+system.network.alias = utl.class()
+
+function system.network.alias:__init__(a, net)
+ self._net = net
+ self._name = a['.name']
+end
+
+
+system.switch = utl.class()
+
+function system.switch:__init__(switch, swdev, net)
+ self._name = switch
+ self._ifname = swdev
+ self._net = net
+
+ if not system._switches[switch] then
+ local x = io.popen("swconfig dev %q help 2>/dev/null" % switch)
+ if x then
+ local desc = x:read("*l")
+
+ if desc then
+ local name, num_ports, num_cpu, num_vlans =
+ desc:match("Switch %d: %S+%((.-)%), ports: (%d+) %(cpu @ (%d+)%), vlans: (%d+)")
+
+ self._model = name
+ self._ports = tonumber(num_ports)
+ self._cpuport = tonumber(num_cpu)
+ self._vlans = tonumber(num_vlans)
+ end
+
+ x:close()
+
+ elseif nfs.access("/proc/switch/%s" % switch) then
+ self._model = self:_proc("driver", switch)
+ self._ports = self:_proc_count("port", 6)
+ self._vlans = self:_proc_count("vlan", 16)
+ end
+
+ -- defaults
+ self._model = self._model or switch
+ self._ports = self._ports or 6
+ self._vlans = self._vlans or 16
+ self._cpuport = self._cpuport or 5
+
+ system._switches[switch] = self
+ else
+ self._model = system._switches[switch]._model
+ self._ports = system._switches[switch]._ports
+ self._vlans = system._switches[switch]._vlans
+ self._cpuport = system._switches[switch]._cpuport
+ end
+end
+
+function system.switch:_proc(path, default)
+ local data = nfs.readfile("/proc/switch/%s/%s" %{ self._name, path })
+ if data then
+ return data:gsub("%s+$", "")
+ end
+ return default
+end
+
+function system.switch:_proc_count(path, default)
+ local cnt = 0
+ for _ in nfs.dir("/proc/switch/%s/%s" %{ self._name, path }) do
+ cnt = cnt + 1
+ end
+ return cnt > 0 and cnt or default
+end
+
+function system.switch:name()
+ return self._name
+end
+
+function system.switch:model()
+ return self._model
+end
+
+function system.switch:num_possible_vlans()
+ return self._vlans
+end
+
+function system.switch:num_active_vlans()
+ local cnt = 0
+ uci:foreach("network2", "switch_vlan",
+ function(s)
+ if s.device == self._name then cnt = cnt + 1 end
+ end)
+ return cnt
+end
+
+function system.switch:vlans()
+ local index = 0
+ local vlans = { }
+
+ uci:foreach("network2", "switch_vlan",
+ function(s)
+ if s.device == self._name and tonumber(s.vlan) then
+ vlans[#vlans+1] = tonumber(s.vlan)
+ end
+ end)
+
+ return function()
+ if index <= #vlans then
+ index = index + 1
+ return system.vlan(vlans[index], self)
+ else
+ return nil
+ end
+ end
+end
+
+function system.switch:num_ports()
+ return self._ports
+end
+
+function system.switch:delete_vlan(vlan)
+ local rv = false
+
+ uci:foreach("network2", "switch_vlan",
+ function(s)
+ if s.device == self._name and tonumber(s.vlan) == vlan then
+ rv = true
+ uci:delete("network2", s['.name'])
+
+ if system._vlans[s.device] and system._vlans[s.device][vlan] then
+ table.remove(system._vlans[s.device], vlan)
+ end
+
+ return false
+ end
+ end)
+
+ return rv
+end
+
+function system.switch:print()
+ print("Switch:", self._model)
+ print(" Ports:", self._ports, "Cpu:", self._cpuport)
+ print(" Vlans:", self._vlans)
+end
+
+
+system.vlan = utl.class()
+
+function system.vlan:__init__(vlan, switch, iface)
+ self._vlan = vlan
+ self._switch = switch
+ self._iface = iface
+
+ local swid = (switch and switch:name()) or (iface and iface:name()) or ""
+
+ if not system._vlans[swid] or not system._vlans[swid][vlan] then
+ self._ports = { }
+
+ if switch then
+ uci:foreach("network2", "switch_vlan",
+ function(s)
+ if s.device == switch:name() and tonumber(s.vlan) == vlan then
+ local p
+ for _, p in ipairs(uci:list("network2", s['.name'], "ports")) do
+ self._ports[#self._ports+1] = system.vlan.port(p, self)
+ end
+ self._name = s['.name']
+ end
+ end)
+ else
+ self._ports[#self._ports+1] = system.vlan.port("0t", self)
+ end
+
+ system._vlans[swid] = system._vlans[swid] or { }
+ system._vlans[swid][vlan] = self
+ else
+ self._ports = system._vlans[swid][vlan]._ports
+ end
+end
+
+function system.vlan:name()
+ return self._name
+end
+
+function system.vlan:number()
+ return self._vlan
+end
+
+function system.vlan:switch()
+ return self._switch
+end
+
+function system.vlan:interface()
+ return self._iface
+end
+
+function system.vlan:is_software()
+ return (self._switch == nil)
+end
+
+function system.vlan:is_hardware()
+ return not self:is_software()
+end
+
+function system.vlan:num_ports()
+ return #self._ports
+end
+
+function system.vlan:ports()
+ local index = 0
+ return function()
+ if index <= #self._ports then
+ index = index + 1
+ return self._ports[index]
+ else
+ return nil
+ end
+ end
+end
+
+function system.vlan:_update()
+ local i
+ local ports = { }
+
+ for i = 1, #self._ports do
+ ports[#ports+1] = self._ports[i]:string()
+ end
+
+ uci:set("network2", self._name, "ports", table.concat(ports, " "))
+end
+
+function system.vlan:delete_port(port)
+ if self._switch then
+ local i
+ for i = 1, #self._ports do
+ if self._ports[i]:number() == port then
+ table.remove(self._ports, i)
+ self:_update()
+ return true
+ end
+ end
+ end
+ return false
+end
+
+function system.vlan:print()
+ print(" Vlan:", self._vlan, "Software?", self:is_software())
+ local p
+ for p in self:ports() do
+ p:print()
+ end
+end
+
+
+system.vlan.port = utl.class()
+
+function system.vlan.port:__init__(port, vlan)
+ local num, tag = port:match("^(%d+)([tu]?)")
+
+ self._vlan = vlan
+ self._port = tonumber(num)
+ self._tagged = (tag == "t")
+end
+
+function system.vlan.port:number()
+ return self._port
+end
+
+function system.vlan.port:vlan()
+ return self._vlan
+end
+
+function system.vlan.port:string()
+ return "%i%s" %{ self._port, self._tagged ? "t" : "" }
+end
+
+function system.vlan.port:is_tagged()
+ return self._tagged
+end
+
+function system.vlan.port:print()
+ print(" Port:", self._port, "Tagged:", self._tagged)
+end
+
+
+-- ------------------------------
+
+local s = system()
+
+s:print()
+
+s:find_network("wan"):print()
+s:find_interface("eth0"):parent():print()
+
+]==]
diff --git a/libs/uci/luasrc/model/uci.lua b/libs/core/luasrc/model/uci.lua
index 66bd0a026..66bd0a026 100644
--- a/libs/uci/luasrc/model/uci.lua
+++ b/libs/core/luasrc/model/uci.lua
diff --git a/libs/uci/luasrc/model/uci/bind.lua b/libs/core/luasrc/model/uci/bind.lua
index 9472dabeb..9472dabeb 100644
--- a/libs/uci/luasrc/model/uci/bind.lua
+++ b/libs/core/luasrc/model/uci/bind.lua
diff --git a/libs/uci/root/etc/config/ucitrack b/libs/core/root/etc/config/ucitrack
index 7b47cc8d5..7b47cc8d5 100644
--- a/libs/uci/root/etc/config/ucitrack
+++ b/libs/core/root/etc/config/ucitrack
diff --git a/libs/uci/root/sbin/luci-reload b/libs/core/root/sbin/luci-reload
index 24cf76064..24cf76064 100755
--- a/libs/uci/root/sbin/luci-reload
+++ b/libs/core/root/sbin/luci-reload