X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=libs%2Fcore%2Fluasrc%2Fmodel%2Fnetwork.lua;h=607276f3c8f4df8930ed27f6a4cb5cc13319b601;hp=548c85597e4af6d706cdf95b89395879550f9fc0;hb=044b011051086b9cb845e497c0a620cdecd038a6;hpb=eb7a72f2513c79909386d1dce214b7ed184c398d diff --git a/libs/core/luasrc/model/network.lua b/libs/core/luasrc/model/network.lua index 548c85597..607276f3c 100644 --- a/libs/core/luasrc/model/network.lua +++ b/libs/core/luasrc/model/network.lua @@ -38,7 +38,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", "^lo$" } +IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^lo$" } IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" } @@ -585,6 +585,44 @@ function del_wifinet(self, net) return false end +function get_status_by_route(self, addr, mask) + local _, object + for _, object in ipairs(_ubus:objects()) do + local net = object:match("^network%.interface%.(.+)") + if net then + local s = _ubus:call(object, "status", {}) + if s and s.route then + local rt + for _, rt in ipairs(s.route) do + if rt.enabled and rt.target == addr and rt.mask == mask then + return net, s + end + end + end + end + end +end + +function get_wannet(self) + local net = self:get_status_by_route("0.0.0.0", 0) + return net and network(net) +end + +function get_wandev(self) + local _, stat = self:get_status_by_route("0.0.0.0", 0) + return stat and interface(stat.l3_device or stat.device) +end + +function get_wan6net(self) + local net = self:get_status_by_route("::", 0) + return net and network(net) +end + +function get_wan6dev(self) + local _, stat = self:get_status_by_route("::", 0) + return stat and interface(stat.l3_device or stat.device) +end + function network(name, proto) if name then @@ -609,11 +647,12 @@ end function protocol._ubus(self, field) if not _ubusnetcache[self.sid] then _ubusnetcache[self.sid] = _ubus:call("network.interface.%s" % self.sid, - "status", { }) + "status", { }) end - - return _ubusnetcache[self.sid] and (field and _ubusnetcache[self.sid][field] - or _ubusnetcache[self.sid]) + if _ubusnetcache[self.sid] and field then + return _ubusnetcache[self.sid][field] + end + return _ubusnetcache[self.sid] end function protocol.get(self, opt) @@ -625,36 +664,28 @@ function protocol.set(self, opt, val) end function protocol.ifname(self) - local p = self:proto() - if self:is_bridge() then - return "br-" .. self.sid - elseif self:is_virtual() then - return p .. "-" .. self.sid + local ifname + if self:is_floating() then + ifname = self:_ubus("l3_device") else + ifname = self:_ubus("device") + end + if not ifname then local num = { } - local dev = _uci_real:get("network", self.sid, "ifname") or - _uci_state:get("network", self.sid, "ifname") - - dev = (type(dev) == "table") and dev[1] or dev - dev = (dev ~= nil) and dev:match("%S+") - - if not dev then - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] - and num[s.device] + 1 or 1 + _uci_real:foreach("wireless", "wifi-iface", + function(s) + if s.device then + num[s.device] = num[s.device] + and num[s.device] + 1 or 1 - if s.network == self.sid then - dev = "%s.network%d" %{ s.device, num[s.device] } - return false - end + if s.network == self.sid then + ifname = "%s.network%d" %{ s.device, num[s.device] } + return false end - end) - end - - return dev + end + end) end + return ifname end function protocol.proto(self) @@ -713,7 +744,7 @@ end function protocol.gwaddr(self) local _, route - for _, route in ipairs(self:_ubus("route")) do + for _, route in ipairs(self:_ubus("route") or { }) do if route.target == "0.0.0.0" and route.mask == 0 then return route.nexthop end @@ -723,7 +754,7 @@ end function protocol.dnsaddrs(self) local dns = { } local _, addr - for _, addr in ipairs(self:_ubus("dns-server")) do + for _, addr in ipairs(self:_ubus("dns-server") or { }) do if not addr:match(":") then dns[#dns+1] = addr end @@ -739,7 +770,7 @@ end function protocol.gw6addr(self) local _, route - for _, route in ipairs(self:_ubus("route")) do + for _, route in ipairs(self:_ubus("route") or { }) do if route.target == "::" and route.mask == 0 then return ipc.IPv6(route.nexthop):string() end @@ -749,7 +780,7 @@ end function protocol.dns6addrs(self) local dns = { } local _, addr - for _, addr in ipairs(self:_ubus("dns-server")) do + for _, addr in ipairs(self:_ubus("dns-server") or { }) do if addr:match(":") then dns[#dns+1] = addr end @@ -789,9 +820,12 @@ function protocol.is_empty(self) _uci_real:foreach("wireless", "wifi-iface", function(s) - if s.network == self.sid then - rv = false - return false + local n + for n in utl.imatch(s.network) do + if n == self.sid then + rv = false + return false + end end end) @@ -802,16 +836,10 @@ end function protocol.add_interface(self, ifname) ifname = _M:ifnameof(ifname) if ifname and not self:is_floating() then - -- remove the interface from all ifaces - _uci_real:foreach("network", "interface", - function(s) - _filter("network", s['.name'], "ifname", ifname) - end) - -- if its a wifi interface, change its network option local wif = _wifi_lookup(ifname) if wif then - _uci_real:set("wireless", wif, "network", self.sid) + _append("wireless", wif, "network", self.sid) -- add iface to our iface list else @@ -825,7 +853,7 @@ function protocol.del_interface(self, ifname) if ifname and not self:is_floating() then -- if its a wireless interface, clear its network option local wif = _wifi_lookup(ifname) - if wif then _uci_real:delete("wireless", wif, "network") end + if wif then _filter("wireless", wif, "network", self.sid) end -- remove the interface _filter("network", self.sid, "ifname", ifname) @@ -916,7 +944,12 @@ function protocol.contains_interface(self, ifname) local wif = _wifi_lookup(ifname) if wif then - return (_uci_real:get("wireless", wif, "network") == self.sid) + local n + for n in utl.imatch(_uci_real:get("wireless", wif, "network")) do + if n == self.sid then + return true + end + end end end @@ -947,9 +980,10 @@ function interface._ubus(self, field) _ubusdevcache[self.ifname] = _ubus:call("network.device", "status", { name = self.ifname }) end - return _ubusdevcache[self.ifname] and - (field and _ubusdevcache[self.ifname][field] or - _ubusdevcache[self.ifname]) + if _ubusdevcache[self.ifname] and field then + return _ubusdevcache[self.ifname][field] + end + return _ubusdevcache[self.ifname] end function interface.name(self) @@ -1074,7 +1108,10 @@ function interface.is_bridgeport(self) end local function uint(x) - return (x < 0) and ((2^32) + x) or x + if x then + return (x < 0) and ((2^32) + x) or x + end + return 0 end function interface.tx_bytes(self) @@ -1098,24 +1135,25 @@ function interface.rx_packets(self) end function interface.get_network(self) - if not self.network then - if self.dev and self.dev.network then - self.network = _M:get_network(self.dev.network) - end - end + return self:get_networks()[1] +end - if not self.network then - local net +function interface.get_networks(self) + if not self.networks then + local nets = { } + local _, net for _, net in ipairs(_M:get_networks()) do if net:contains_interface(self.ifname) or net:ifname() == self.ifname then - self.network = net - return net + nets[#nets+1] = net end end + table.sort(nets, function(a, b) return a.sid < b.sid end) + self.networks = nets + return nets else - return self.network + return self.networks end end @@ -1435,10 +1473,19 @@ function wifinet.adminlink(self) end function wifinet.get_network(self) - local net = tostring(self.iwdata.network) - if net and _uci_real:get("network", net) == "interface" then - return network(net) + return self:get_networks()[1] +end + +function wifinet.get_networks(self) + local nets = { } + local net + for net in utl.imatch(tostring(self.iwdata.network)) do + if _uci_real:get("network", net) == "interface" then + nets[#nets+1] = network(net) + end end + table.sort(nets, function(a, b) return a.sid < b.sid end) + return nets end function wifinet.get_interface(self)