libs/core: fixes for network model
[project/luci.git] / libs / core / luasrc / model / network.lua
index 3a7e38a..718f07d 100644 (file)
@@ -22,6 +22,7 @@ local type, pairs, ipairs, table, i18n
 
 local lmo = require "lmo"
 local nxo = require "nixio"
 
 local lmo = require "lmo"
 local nxo = require "nixio"
+local nfs = require "nixio.fs"
 local iwi = require "iwinfo"
 local ipc = require "luci.ip"
 local utl = require "luci.util"
 local iwi = require "iwinfo"
 local ipc = require "luci.ip"
 local utl = require "luci.util"
@@ -31,7 +32,7 @@ module "luci.model.network"
 
 
 local ub = uct.bind("network")
 
 
 local ub = uct.bind("network")
-local ifs, brs
+local ifs, brs, sws
 
 function init(cursor)
        if cursor then
 
 function init(cursor)
        if cursor then
@@ -41,11 +42,13 @@ function init(cursor)
 
                ifs = { }
                brs = { }
 
                ifs = { }
                brs = { }
+               sws = { }
 
                -- read interface information
                local n, i
                for n, i in ipairs(nxo.getifaddrs()) do
                        local name = i.name:match("[^:]+")
 
                -- read interface information
                local n, i
                for n, i in ipairs(nxo.getifaddrs()) do
                        local name = i.name:match("[^:]+")
+                       local prnt = name:match("^([^%.]+)%.")
 
                        if not _M:ignore_interface(name) then
                                ifs[name] = ifs[name] or {
 
                        if not _M:ignore_interface(name) then
                                ifs[name] = ifs[name] or {
@@ -57,6 +60,11 @@ function init(cursor)
                                        ip6addrs = { }
                                }
 
                                        ip6addrs = { }
                                }
 
+                               if prnt then
+                                       sws[name] = true
+                                       sws[prnt] = true
+                               end
+
                                if i.family == "packet" then
                                        ifs[name].flags   = i.flags
                                        ifs[name].stats   = i.data
                                if i.family == "packet" then
                                        ifs[name].flags   = i.flags
                                        ifs[name].stats   = i.data
@@ -94,6 +102,10 @@ function init(cursor)
        end
 end
 
        end
 end
 
+function has_ipv6(self)
+       return nfs.access("/proc/net/ipv6_route")
+end
+
 function add_network(self, n, options)
        if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not self:get_network(n) then
                if ub.uci:section("network", "interface", n, options) then
 function add_network(self, n, options)
        if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not self:get_network(n) then
                if ub.uci:section("network", "interface", n, options) then
@@ -224,9 +236,7 @@ end
 function network.get_interfaces(self)
        local ifaces = { }
        local iface
 function network.get_interfaces(self)
        local ifaces = { }
        local iface
-       for _, iface in ub:list(
-               (self:ifname() or '') .. ' ' .. (self:device() or '')
-       ) do
+       for _, iface in ipairs(ub:list(self:ifname())) do
                iface = iface:match("[^:]+")
                if ifs[iface] then
                        ifaces[#ifaces+1] = interface(iface)
                iface = iface:match("[^:]+")
                if ifs[iface] then
                        ifaces[#ifaces+1] = interface(iface)
@@ -237,9 +247,7 @@ end
 
 function network.contains_interface(self, iface)
        local i
 
 function network.contains_interface(self, iface)
        local i
-       local ifaces = ub:list(
-               (self:ifname() or '') .. ' ' .. (self:device() or '')
-       )
+       local ifaces = ub:list(self:ifname())
 
        if type(iface) ~= "string" then
                iface = iface:name()
 
        if type(iface) ~= "string" then
                iface = iface:name()
@@ -268,12 +276,24 @@ function interface.name(self)
        return self.ifname
 end
 
        return self.ifname
 end
 
+function interface.mac(self)
+       return self.dev.macaddr or "00:00:00:00:00:00"
+end
+
+function interface.ipaddrs(self)
+       return self.dev.ipaddrs or { }
+end
+
+function interface.ip6addrs(self)
+       return self.dev.ip6addrs or { }
+end
+
 function interface.type(self)
        if iwi.type(self.ifname) and iwi.type(self.ifname) ~= "dummy" then
                return "wifi"
        elseif brs[self.ifname] then
                return "bridge"
 function interface.type(self)
        if iwi.type(self.ifname) and iwi.type(self.ifname) ~= "dummy" then
                return "wifi"
        elseif brs[self.ifname] then
                return "bridge"
-       elseif self.ifname:match("%.") then
+       elseif sws[self.ifname] or self.ifname:match("%.") then
                return "switch"
        else
                return "ethernet"
                return "switch"
        else
                return "ethernet"
@@ -298,12 +318,28 @@ function interface.ports(self)
                local iface
                local ifaces = { }
                for _, iface in ipairs(self.br.ifnames) do
                local iface
                local ifaces = { }
                for _, iface in ipairs(self.br.ifnames) do
-                       ifaces[#ifaces+1] = interface(iface)
+                       ifaces[#ifaces+1] = interface(iface.name)
                end
                return ifaces
        end
 end
 
                end
                return ifaces
        end
 end
 
+function interface.bridge_id(self)
+       if self.br then
+               return self.br.id
+       else
+               return nil
+       end
+end
+
+function interface.bridge_stp(self)
+       if self.br then
+               return self.br.stp
+       else
+               return false
+       end
+end
+
 function interface.is_up(self)
        return self.dev.flags and self.dev.flags.up
 end
 function interface.is_up(self)
        return self.dev.flags and self.dev.flags.up
 end
@@ -312,12 +348,41 @@ function interface.is_bridge(self)
        return (self:type() == "bridge")
 end
 
        return (self:type() == "bridge")
 end
 
+function interface.is_bridgeport(self)
+       return self.dev and self.dev.bridge and true or false
+end
+
+function interface.tx_bytes(self)
+       return self.dev and self.dev.stats
+               and self.dev.stats.tx_bytes or 0
+end
+
+function interface.rx_bytes(self)
+       return self.dev and self.dev.stats
+               and self.dev.stats.rx_bytes or 0
+end
+
+function interface.tx_packets(self)
+       return self.dev and self.dev.stats
+               and self.dev.stats.tx_packets or 0
+end
+
+function interface.rx_packets(self)
+       return self.dev and self.dev.stats
+               and self.dev.stats.rx_packets or 0
+end
+
 function interface.get_network(self)
 function interface.get_network(self)
-       local net
-       for _, net in ipairs(_M:get_networks()) do
-               if net:contains_interface(self.ifname) then
-                       return net
+       if not self.network then
+               local net
+               for _, net in ipairs(_M:get_networks()) do
+                       if net:contains_interface(self.ifname) then
+                               self.network = net
+                               return net
+                       end
                end
                end
+       else
+               return self.network
        end
 end
 
        end
 end