summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2009-10-15 16:30:17 +0000
committerJo-Philipp Wich <jow@openwrt.org>2009-10-15 16:30:17 +0000
commit09c5e7241ad345229fe2eea5379cc8716171abb0 (patch)
tree37373832a8dc213c31f3b6ad7aca0dca349cd617
parentd8facca1b3441419ee976003c24cab0601b0b408 (diff)
libs/core: implement special treatment of wireless in network model
-rw-r--r--libs/core/luasrc/model/network.lua110
-rw-r--r--libs/core/luasrc/model/network/wireless.lua148
2 files changed, 247 insertions, 11 deletions
diff --git a/libs/core/luasrc/model/network.lua b/libs/core/luasrc/model/network.lua
index 718f07dc4..debf3dba4 100644
--- a/libs/core/luasrc/model/network.lua
+++ b/libs/core/luasrc/model/network.lua
@@ -17,8 +17,8 @@ limitations under the License.
]]--
-local type, pairs, ipairs, table, i18n
- = type, pairs, ipairs, table, luci.i18n
+local type, pairs, ipairs, loadfile, table, i18n
+ = type, pairs, ipairs, loadfile, table, luci.i18n
local lmo = require "lmo"
local nxo = require "nixio"
@@ -30,6 +30,28 @@ local uct = require "luci.model.uci.bind"
module "luci.model.network"
+-- load extensions
+local ext
+local handler = { }
+
+for ext in nfs.glob(utl.libpath() .. "/model/network/*.lua") do
+ if nfs.access(ext) then
+ local m = loadfile(ext)
+ if m then
+ handler[#handler+1] = m()
+ end
+ end
+end
+
+function foreach_handler(code, ...)
+ local h
+ for _, h in ipairs(handler) do
+ if code(h, ...) then
+ return true
+ end
+ end
+ return false
+end
local ub = uct.bind("network")
local ifs, brs, sws
@@ -44,6 +66,12 @@ function init(cursor)
brs = { }
sws = { }
+ -- init handler
+ foreach_handler(function(h)
+ h:init(cursor)
+ h:find_interfaces(ifs, brs)
+ end)
+
-- read interface information
local n, i
for n, i in ipairs(nxo.getifaddrs()) do
@@ -75,7 +103,7 @@ function init(cursor)
ifs[name].ip6addrs[#ifs[name].ip6addrs+1] = ipc.IPv6(i.addr, i.netmask)
end
end
- end
+ end
-- read bridge informaton
local b, l
@@ -150,6 +178,8 @@ function del_network(self, n)
ub.uci:delete("network", s['.name'])
end
end)
+
+ foreach_handler(function(h) h:del_network(n) end)
end
return r
end
@@ -179,6 +209,8 @@ function rename_network(self, old, new)
ub.uci:set("network", s['.name'], "interface", new)
end
end)
+
+ foreach_handler(function(h) h:rename_network(old, new) end)
end
end
return r or false
@@ -198,8 +230,12 @@ function get_interfaces(self)
end
function ignore_interface(self, x)
- return (x:match("^wmaster%d") or x:match("^wifi%d")
- or x:match("^hwsim%d") or x:match("^imq%d") or x == "lo")
+ if foreach_handler(function(h) return h:ignore_interface(x) end) then
+ return true
+ else
+ return (x:match("^wmaster%d") or x:match("^wifi%d")
+ or x:match("^hwsim%d") or x:match("^imq%d") or x == "lo")
+ end
end
@@ -218,11 +254,27 @@ function network.is_bridge(self)
end
function network.add_interface(self, ifname)
+ local ifaces, iface
+
if type(ifname) ~= "string" then
- ifname = ifname:name()
+ ifaces = { ifname:name() }
+ else
+ ifaces = ub:list(ifname)
end
- if ifs[ifname] then
- self:ifname(ub:list((self:ifname() or ''), ifname))
+
+ for _, iface in ipairs(ifaces) do
+ if ifs[iface] then
+ -- make sure the interface is removed from all networks
+ local i = interface(iface)
+ local n = i:get_network()
+ if n then n:del_interface(iface) end
+
+ if ifs[iface].handler then
+ ifs[iface].handler:add_interface(self, iface, ifs[iface])
+ else
+ self:ifname(ub:list((self:ifname() or ''), iface))
+ end
+ end
end
end
@@ -230,7 +282,12 @@ function network.del_interface(self, ifname)
if type(ifname) ~= "string" then
ifname = ifname:name()
end
- self:ifname(ub:list((self:ifname() or ''), nil, ifname))
+
+ if ifs[ifname] and ifs[ifname].handler then
+ ifs[ifname].handler:del_interface(self, ifname, ifs[ifname])
+ else
+ self:ifname(ub:list((self:ifname() or ''), nil, ifname))
+ end
end
function network.get_interfaces(self)
@@ -242,6 +299,11 @@ function network.get_interfaces(self)
ifaces[#ifaces+1] = interface(iface)
end
end
+ for iface, _ in pairs(ifs) do
+ if ifs[iface].network == self:name() then
+ ifaces[#ifaces+1] = interface(iface)
+ end
+ end
return ifaces
end
@@ -259,6 +321,12 @@ function network.contains_interface(self, iface)
end
end
+ for i, _ in pairs(ifs) do
+ if ifs[i].dev and ifs[i].dev.network == self:name() then
+ return true
+ end
+ end
+
return false
end
@@ -289,8 +357,8 @@ function interface.ip6addrs(self)
end
function interface.type(self)
- if iwi.type(self.ifname) and iwi.type(self.ifname) ~= "dummy" then
- return "wifi"
+ if self.dev and self.dev.type then
+ return self.dev.type
elseif brs[self.ifname] then
return "bridge"
elseif sws[self.ifname] or self.ifname:match("%.") then
@@ -300,6 +368,22 @@ function interface.type(self)
end
end
+function interface.shortname(self)
+ if self.dev and self.dev.handler then
+ return self.dev.handler:shortname(self)
+ else
+ return self.ifname
+ end
+end
+
+function interface.get_i18n(self)
+ if self.dev and self.dev.handler then
+ return self.dev.handler:get_i18n(self)
+ else
+ return "%s: %q" %{ self:get_type_i18n(), self:name() }
+ end
+end
+
function interface.get_type_i18n(self)
local x = self:type()
if x == "wifi" then
@@ -373,6 +457,10 @@ function interface.rx_packets(self)
end
function interface.get_network(self)
+ if self.dev and self.dev.network then
+ self.network = _M:get_network(self.dev.network)
+ end
+
if not self.network then
local net
for _, net in ipairs(_M:get_networks()) do
diff --git a/libs/core/luasrc/model/network/wireless.lua b/libs/core/luasrc/model/network/wireless.lua
new file mode 100644
index 000000000..ec4131b04
--- /dev/null
+++ b/libs/core/luasrc/model/network/wireless.lua
@@ -0,0 +1,148 @@
+--[[
+LuCI - Network model - Wireless extension
+
+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
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+]]--
+
+local pairs, i18n, uci = pairs, luci.i18n, luci.model.uci
+
+local iwi = require "iwinfo"
+local utl = require "luci.util"
+local uct = require "luci.model.uci.bind"
+
+module "luci.model.network.wireless"
+
+local ub = uct.bind("wireless")
+local st, ifs
+
+function init(self, cursor)
+ cursor:unload("wireless")
+ cursor:load("wireless")
+ ub:init(cursor)
+
+ st = uci.cursor_state()
+ ifs = { }
+
+ local count = 0
+
+ ub.uci:foreach("wireless", "wifi-iface",
+ function(s)
+ count = count + 1
+
+ local device = s.device or "wlan0"
+ local state = st:get_all("wireless", s['.name'])
+ local name = state.ifname or device .. ".network" .. count
+
+ ifs[state and state.ifname or name] = {
+ idx = count,
+ name = state and state.ifname or name,
+ rawname = state and state.ifname or name,
+ flags = { },
+ ipaddrs = { },
+ ip6addrs = { },
+
+ type = "wifi",
+ network = s.network,
+ handler = self,
+ wifi = state or s,
+ sid = s['.name']
+ }
+ end)
+end
+
+function shortname(self, iface)
+ if iface.dev and iface.dev.wifi then
+ return "%s %q" %{
+ i18n.translate("a_s_if_iwmode_" .. (iface.dev.wifi.mode or "ap")),
+ iface.dev.wifi.ssid or iface.dev.wifi.bssid or "(hidden)"
+ }
+ else
+ return iface:name()
+ end
+end
+
+function get_i18n(self, iface)
+ if iface.dev and iface.dev.wifi then
+ return "%s: %s %q" %{
+ i18n.translate("a_s_if_wifinet", "Wireless Network"),
+ i18n.translate("a_s_if_iwmode_" .. (iface.dev.wifi.mode or "ap"), iface.dev.wifi.mode or "AP"),
+ iface.dev.wifi.ssid or iface.dev.wifi.bssid or "(hidden)"
+ }
+ else
+ return "%s: %q" %{ i18n.translate("a_s_if_wifinet", "Wireless Network"), iface:name() }
+ end
+end
+
+function rename_network(self, old, new)
+ local i
+ for i, _ in pairs(ifs) do
+ if ifs[i].network == old then
+ ifs[i].network = new
+ end
+ end
+
+ ub.uci:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.network == old then
+ if new then
+ ub.uci:set("wireless", s['.name'], "network", new)
+ else
+ ub.uci:delete("wireless", s['.name'], "network")
+ end
+ end
+ end)
+end
+
+function del_network(self, old)
+ return self:rename_network(old, nil)
+end
+
+function find_interfaces(self, iflist, brlist)
+ local iface
+ for iface, _ in pairs(ifs) do
+ iflist[iface] = ifs[iface]
+ end
+end
+
+function ignore_interface(self, iface)
+ if ifs and ifs[iface] then
+ return false
+ else
+ return iwi.type(iface) and true or false
+ end
+end
+
+function add_interface(self, net, iface)
+ if ifs and ifs[iface] and ifs[iface].sid then
+ ub.uci:set("wireless", ifs[iface].sid, "network", net:name())
+ ifs[iface].network = net:name()
+ return true
+ end
+
+ return false
+end
+
+function del_interface(self, net, iface)
+ if ifs and ifs[iface] and ifs[iface].sid then
+ ub.uci:delete("wireless", ifs[iface].sid, "network")
+ --return true
+ end
+
+ return false
+end
+
+return _M
+