diff options
-rw-r--r-- | libs/core/luasrc/model/network.lua | 110 | ||||
-rw-r--r-- | libs/core/luasrc/model/network/wireless.lua | 148 |
2 files changed, 247 insertions, 11 deletions
diff --git a/libs/core/luasrc/model/network.lua b/libs/core/luasrc/model/network.lua index 718f07dc4b..debf3dba49 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 0000000000..ec4131b046 --- /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 + |