Merge pull request #2006 from dibdot/adblock
[oweals/luci.git] / modules / luci-base / luasrc / model / network.lua
index 056fc67b144fce476bb05b03913a0f060e88fd31..cce559aab1740166f9efa82989f01b87f9f5c3db 100644 (file)
@@ -23,6 +23,22 @@ IFACE_PATTERNS_VIRTUAL  = { }
 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" }
 
+IFACE_ERRORS = {
+       CONNECT_FAILED                  = lng.translate("Connection attempt failed"),
+       INVALID_ADDRESS                 = lng.translate("IP address in invalid"),
+       INVALID_GATEWAY                 = lng.translate("Gateway address is invalid"),
+       INVALID_LOCAL_ADDRESS   = lng.translate("Local IP address is invalid"),
+       MISSING_ADDRESS                 = lng.translate("IP address is missing"),
+       MISSING_PEER_ADDRESS    = lng.translate("Peer address is missing"),
+       NO_DEVICE                               = lng.translate("Network device is not present"),
+       NO_IFACE                                = lng.translate("Unable to determine device name"),
+       NO_IFNAME                               = lng.translate("Unable to determine device name"),
+       NO_WAN_ADDRESS                  = lng.translate("Unable to determine external IP address"),
+       NO_WAN_LINK                             = lng.translate("Unable to determine upstream interface"),
+       PEER_RESOLVE_FAIL               = lng.translate("Unable to resolve peer host name"),
+       PIN_FAILED                              = lng.translate("PIN code rejected")
+}
+
 
 protocol = utl.class()
 
@@ -495,6 +511,17 @@ function register_pattern_virtual(self, pat)
        IFACE_PATTERNS_VIRTUAL[#IFACE_PATTERNS_VIRTUAL+1] = pat
 end
 
+function register_error_code(self, code, message)
+       if type(code) == "string" and
+          type(message) == "string" and
+          not IFACE_ERRORS[code]
+       then
+               IFACE_ERRORS[code] = message
+               return true
+       end
+
+       return false
+end
 
 function has_ipv6(self)
        return nfs.access("/proc/net/ipv6_route")
@@ -520,6 +547,13 @@ end
 function get_network(self, n)
        if n and _uci:get("network", n) == "interface" then
                return network(n)
+       elseif n then
+               local stat = utl.ubus("network.interface", "status", { interface = n })
+               if type(stat) == "table" and
+                  type(stat.proto) == "string"
+               then
+                       return network(n, stat.proto)
+               end
        end
 end
 
@@ -532,6 +566,23 @@ function get_networks(self)
                        nls[s['.name']] = network(s['.name'])
                end)
 
+       local dump = utl.ubus("network.interface", "dump", { })
+       if type(dump) == "table" and
+          type(dump.interface) == "table"
+       then
+               local _, net
+               for _, net in ipairs(dump.interface) do
+                       if type(net) == "table" and
+                          type(net.proto) == "string" and
+                          type(net.interface) == "string"
+                       then
+                               if not nls[net.interface] then
+                                       nls[net.interface] = network(net.interface, net.proto)
+                               end
+                       end
+               end
+       end
+
        local n
        for n in utl.kspairs(nls) do
                nets[#nets+1] = nls[n]
@@ -629,7 +680,7 @@ function get_interface(self, i)
        if _interfaces[i] or _wifi_iface(i) then
                return interface(i)
        else
-               local netid = _wifi_netid_by_netname(i)
+               local netid = _wifi_netid_by_sid(i)
                return netid and interface(netid)
        end
 end
@@ -929,6 +980,16 @@ function protocol.metric(self)
        return self:_ubus("metric") or 0
 end
 
+function protocol.zonename(self)
+       local d = self:_ubus("data")
+
+       if type(d) == "table" and type(d.zone) == "string" then
+               return d.zone
+       end
+
+       return nil
+end
+
 function protocol.ipaddr(self)
        local addrs = self:_ubus("ipv4-address")
        return addrs and #addrs > 0 and addrs[1].address
@@ -1043,6 +1104,22 @@ function protocol.ip6prefix(self)
        end
 end
 
+function protocol.errors(self)
+       local _, err, rv
+       local errors = self:_ubus("errors")
+       if type(errors) == "table" then
+               for _, err in ipairs(errors) do
+                       if type(err) == "table" and
+                          type(err.code) == "string"
+                       then
+                               rv = rv or { }
+                               rv[#rv+1] = IFACE_ERRORS[err.code] or lng.translatef("Unknown error (%s)", err.code)
+                       end
+               end
+       end
+       return rv
+end
+
 function protocol.is_bridge(self)
        return (not self:is_virtual() and self:type() == "bridge")
 end
@@ -1063,6 +1140,24 @@ function protocol.is_floating(self)
        return false
 end
 
+function protocol.is_dynamic(self)
+       return (self:_ubus("dynamic") == true)
+end
+
+function protocol.is_alias(self)
+       local ifn, parent = nil, nil
+
+       for ifn in utl.imatch(_uci:get("network", self.sid, "ifname")) do
+               if #ifn > 1 and ifn:byte(1) == 64 then
+                       parent = ifn:sub(2)
+               elseif parent ~= nil then
+                       parent = nil
+               end
+       end
+
+       return parent
+end
+
 function protocol.is_empty(self)
        if self:is_floating() then
                return false
@@ -1081,6 +1176,10 @@ function protocol.is_empty(self)
        end
 end
 
+function protocol.is_up(self)
+       return (self:_ubus("up") == true)
+end
+
 function protocol.add_interface(self, ifname)
        ifname = _M:ifnameof(ifname)
        if ifname and not self:is_floating() then
@@ -1116,12 +1215,16 @@ function protocol.get_interface(self)
                _bridge["br-" .. self.sid] = true
                return interface("br-" .. self.sid, self)
        else
-               local ifn = nil
-               local num = { }
+               local ifn = self:_ubus("l3_device") or self:_ubus("device")
+               if ifn then
+                       return interface(ifn, self)
+               end
+
                for ifn in utl.imatch(_uci:get("network", self.sid, "ifname")) do
                        ifn = ifn:match("^[^:/]+")
                        return ifn and interface(ifn, self)
                end
+
                ifn = _wifi_netid_by_netname(self.sid)
                return ifn and interface(ifn, self)
        end
@@ -1245,7 +1348,9 @@ function interface.ip6addrs(self)
 end
 
 function interface.type(self)
-       if self.wif or _wifi_iface(self.ifname) then
+       if self.ifname and self.ifname:byte(1) == 64 then
+               return "alias"
+       elseif self.wif or _wifi_iface(self.ifname) then
                return "wifi"
        elseif _bridge[self.ifname] then
                return "bridge"
@@ -1273,7 +1378,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() or self.wif:id()
+                       self.wif:active_ssid() or self.wif:active_bssid() or self.wif:id() or "?"
                }
        else
                return "%s: %q" %{ self:get_type_i18n(), self:name() }
@@ -1282,7 +1387,9 @@ end
 
 function interface.get_type_i18n(self)
        local x = self:type()
-       if x == "wifi" then
+       if x == "alias" then
+               return lng.translate("Alias Interface")
+       elseif x == "wifi" then
                return lng.translate("Wireless Adapter")
        elseif x == "bridge" then
                return lng.translate("Bridge")
@@ -1335,7 +1442,11 @@ function interface.bridge_stp(self)
 end
 
 function interface.is_up(self)
-       return self:_ubus("up") or false
+       local up = self:_ubus("up")
+       if up == nil then
+               up = (self:type() == "alias")
+       end
+       return up or false
 end
 
 function interface.is_bridge(self)
@@ -1428,7 +1539,7 @@ function wifidev.hwmodes(self)
 end
 
 function wifidev.get_i18n(self)
-       local t = "Generic"
+       local t = self.iwinfo.hardware_name or "Generic"
        if self.iwinfo.type == "wl" then
                t = "Broadcom"
        end
@@ -1601,7 +1712,7 @@ end
 function wifinet.ifname(self)
        local ifname = self:ubus("net", "ifname") or self.iwinfo.ifname
        if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
-               ifname = self.wdev
+               ifname = self.netid
        end
        return ifname
 end