X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=modules%2Fluci-base%2Fluasrc%2Fmodel%2Fnetwork.lua;h=d9ef4089c8204d99c5a901c167f382cb385f57b4;hp=81fc416fedd952e9b33aef3b4606621ef37a71e4;hb=ea801ada7d43749fab14e680b78cb5977d7d488c;hpb=23df4ffaf7060fd10e6b3f41ada903d52a55ad03 diff --git a/modules/luci-base/luasrc/model/network.lua b/modules/luci-base/luasrc/model/network.lua index 81fc416fe..d9ef4089c 100644 --- a/modules/luci-base/luasrc/model/network.lua +++ b/modules/luci-base/luasrc/model/network.lua @@ -22,7 +22,7 @@ module "luci.model.network" IFACE_PATTERNS_VIRTUAL = { } -IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^lo$" } +IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^gretap%d", "^ip6gre%d", "^ip6tnl%d", "^tunl%d", "^lo$" } IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" } @@ -30,7 +30,7 @@ protocol = utl.class() local _protocols = { } -local _interfaces, _bridge, _switch, _tunnel +local _interfaces, _bridge, _switch, _tunnel, _swtopo local _ubusnetcache, _ubusdevcache, _ubuswificache local _uci @@ -190,10 +190,9 @@ function _iface_ignore(x) return true end end - return _iface_virtual(x) + return false end - function init(cursor) _uci = cursor or _uci or uci.cursor() @@ -201,6 +200,7 @@ function init(cursor) _bridge = { } _switch = { } _tunnel = { } + _swtopo = { } _ubusnetcache = { } _ubusdevcache = { } @@ -210,13 +210,12 @@ function init(cursor) local n, i for n, i in ipairs(nxo.getifaddrs()) do local name = i.name:match("[^:]+") - local prnt = name:match("^([^%.]+)%.") if _iface_virtual(name) then _tunnel[name] = true end - if _tunnel[name] or not _iface_ignore(name) then + if _tunnel[name] or not (_iface_ignore(name) or _iface_virtual(name)) then _interfaces[name] = _interfaces[name] or { idx = i.ifindex or n, name = name, @@ -226,11 +225,6 @@ function init(cursor) ip6addrs = { } } - if prnt then - _switch[name] = true - _switch[prnt] = true - end - if i.family == "packet" then _interfaces[name].flags = i.flags _interfaces[name].stats = i.data @@ -266,6 +260,79 @@ function init(cursor) end end + -- read switch topology + local boardinfo = jsc.parse(nfs.readfile("/etc/board.json") or "") + if type(boardinfo) == "table" and type(boardinfo.switch) == "table" then + local switch, layout + for switch, layout in pairs(boardinfo.switch) do + if type(layout) == "table" and type(layout.ports) == "table" then + local _, port + local ports = { } + local nports = { } + local netdevs = { } + + for _, port in ipairs(layout.ports) do + if type(port) == "table" and + type(port.num) == "number" and + (type(port.role) == "string" or + type(port.device) == "string") + then + local spec = { + num = port.num, + role = port.role or "cpu", + index = port.index or port.num + } + + if port.device then + spec.device = port.device + spec.tagged = port.need_tag + netdevs[tostring(port.num)] = port.device + end + + ports[#ports+1] = spec + + if port.role then + nports[port.role] = (nports[port.role] or 0) + 1 + end + end + end + + table.sort(ports, function(a, b) + if a.role ~= b.role then + return (a.role < b.role) + end + + return (a.index < b.index) + end) + + local pnum, role + for _, port in ipairs(ports) do + if port.role ~= role then + role = port.role + pnum = 1 + end + + if role == "cpu" then + port.label = "CPU (%s)" % port.device + elseif nports[role] > 1 then + port.label = "%s %d" %{ role:upper(), pnum } + pnum = pnum + 1 + else + port.label = role:upper() + end + + port.role = nil + port.index = nil + end + + _swtopo[switch] = { + ports = ports, + netdevs = netdevs + } + end + end + end + return _M end @@ -474,41 +541,23 @@ function get_interface(self, i) end end -local function swdev_from_board_json() - local boardinfo = jsc.parse(nfs.readfile("/etc/board.json") or "") - if type(boardinfo) == "table" and type(boardinfo.network) == "table" then - local net, val - for net, val in pairs(boardinfo.network) do - if type(val) == "table" and type(val.ifname) == "string" and - val.create_vlan == true - then - return val.ifname - end - end - end - return nil -end - function get_interfaces(self) local iface local ifaces = { } - local seen = { } local nfs = { } - local baseof = { } -- find normal interfaces _uci:foreach("network", "interface", function(s) for iface in utl.imatch(s.ifname) do - if not _iface_ignore(iface) and not _wifi_iface(iface) then - seen[iface] = true + if not _iface_ignore(iface) and not _iface_virtual(iface) and not _wifi_iface(iface) then nfs[iface] = interface(iface) end end end) for iface in utl.kspairs(_interfaces) do - if not (seen[iface] or _iface_ignore(iface) or _wifi_iface(iface)) then + if not (nfs[iface] or _iface_ignore(iface) or _iface_virtual(iface) or _wifi_iface(iface)) then nfs[iface] = interface(iface) end end @@ -516,34 +565,32 @@ function get_interfaces(self) -- find vlan interfaces _uci:foreach("network", "switch_vlan", function(s) - if not s.device then + if type(s.ports) ~= "string" or + type(s.device) ~= "string" or + type(_swtopo[s.device]) ~= "table" + then return end - local base = baseof[s.device] - if not base then - if not s.device:match("^eth%d") then - local l - for l in utl.execi("swconfig dev %q help 2>/dev/null" % s.device) do - if not base then - base = l:match("^%w+: (%w+)") - end + local pnum, ptag + for pnum, ptag in s.ports:gmatch("(%d+)([tu]?)") do + local netdev = _swtopo[s.device].netdevs[pnum] + if netdev then + if not nfs[netdev] then + nfs[netdev] = interface(netdev) end - if not base or not base:match("^eth%d") then - base = swdev_from_board_json() or "eth0" + _switch[netdev] = true + + if ptag == "t" then + local vid = tonumber(s.vid or s.vlan) + if vid ~= nil and vid >= 0 and vid <= 4095 then + local iface = "%s.%d" %{ netdev, vid } + if not nfs[iface] then + nfs[iface] = interface(iface) + end + _switch[iface] = true + end end - else - base = s.device - end - baseof[s.device] = base - end - - local vid = tonumber(s.vid or s.vlan) - if vid ~= nil and vid >= 0 and vid <= 4095 then - local iface = "%s.%d" %{ base, vid } - if not seen[iface] then - seen[iface] = true - nfs[iface] = interface(iface) end end end) @@ -666,8 +713,8 @@ function get_status_by_address(self, addr) end function get_wannet(self) - local net = self:get_status_by_route("0.0.0.0", 0) - return net and network(net) + local net, stat = self:get_status_by_route("0.0.0.0", 0) + return net and network(net, stat.proto) end function get_wandev(self) @@ -676,8 +723,8 @@ function get_wandev(self) end function get_wan6net(self) - local net = self:get_status_by_route("::", 0) - return net and network(net) + local net, stat = self:get_status_by_route("::", 0) + return net and network(net, stat.proto) end function get_wan6dev(self) @@ -685,6 +732,10 @@ function get_wan6dev(self) return stat and interface(stat.l3_device or stat.device) end +function get_switch_topologies(self) + return _swtopo +end + function network(name, proto) if name then @@ -899,6 +950,13 @@ function protocol.dns6addrs(self) return dns end +function protocol.ip6prefix(self) + local prefix = self:_ubus("ipv6-prefix") + if prefix and #prefix > 0 then + return "%s/%d" %{ prefix[1].address, prefix[1].mask } + end +end + function protocol.is_bridge(self) return (not self:is_virtual() and self:type() == "bridge") end @@ -1140,10 +1198,7 @@ end function interface.shortname(self) if self.wif then - return "%s %q" %{ - self.wif:active_mode(), - self.wif:active_ssid() or self.wif:active_bssid() - } + return self.wif:shortname() else return self.ifname end @@ -1154,7 +1209,7 @@ function interface.get_i18n(self) return "%s: %s %q" %{ lng.translate("Wireless Network"), self.wif:active_mode(), - self.wif:active_ssid() or self.wif:active_bssid() + self.wif:active_ssid() or self.wif:active_bssid() or self.wif:id() } else return "%s: %q" %{ self:get_type_i18n(), self:name() } @@ -1170,7 +1225,11 @@ function interface.get_type_i18n(self) elseif x == "switch" then return lng.translate("Ethernet Switch") elseif x == "vlan" then - return lng.translate("VLAN Interface") + if _switch[self.ifname] then + return lng.translate("Switch VLAN") + else + return lng.translate("Software VLAN") + end elseif x == "tunnel" then return lng.translate("Tunnel Interface") else @@ -1303,8 +1362,6 @@ function wifidev.get_i18n(self) local t = "Generic" if self.iwinfo.type == "wl" then t = "Broadcom" - elseif self.iwinfo.type == "madwifi" then - t = "Atheros" end local m = "" @@ -1593,7 +1650,7 @@ end function wifinet.shortname(self) return "%s %q" %{ lng.translate(self:active_mode()), - self:active_ssid() or self:active_bssid() + self:active_ssid() or self:active_bssid() or self:id() } end @@ -1601,7 +1658,7 @@ function wifinet.get_i18n(self) return "%s: %s %q (%s)" %{ lng.translate("Wireless Network"), lng.translate(self:active_mode()), - self:active_ssid() or self:active_bssid(), + self:active_ssid() or self:active_bssid() or self:id(), self:ifname() } end