luci-base: implement further ubus calls
authorJo-Philipp Wich <jo@mein.io>
Thu, 6 Jun 2019 17:24:10 +0000 (19:24 +0200)
committerJo-Philipp Wich <jo@mein.io>
Sun, 7 Jul 2019 13:36:25 +0000 (15:36 +0200)
Implement new ubus rpcd backend calls for later use in the frontend:

 - netdevs: dump information about Linux network devices present
 - boardjson: dump /etc/board.json if present
 - offload_support: query whether netfilter offloading is supported

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/root/usr/libexec/rpcd/luci

index c4566210f6ca33338172841d19332b757d37bed2..dba6df0cb9e1b9fe9c9117838e472ec66a2a73c9 100755 (executable)
@@ -196,6 +196,83 @@ local methods = {
                                }
                        end
                end
+       },
+
+       netdevs = {
+               call = function(args)
+                       local dir = fs.dir("/sys/class/net")
+                       local result = { }
+                       if dir then
+                               local dev
+                               for dev in dir do
+                                       if not result[dev] then
+                                               result[dev] = { name = dev }
+                                       end
+
+                                       if fs.access("/sys/class/net/"..dev.."/master") then
+                                               local brname = fs.basename(fs.readlink("/sys/class/net/"..dev.."/master"))
+                                               if not result[brname] then
+                                                       result[brname] = { name = brname }
+                                               end
+
+                                               if not result[brname].ports then
+                                                       result[brname].ports = { }
+                                               end
+
+                                               result[brname].ports[#result[brname].ports+1] = dev
+                                       elseif fs.access("/sys/class/net/"..dev.."/bridge") then
+                                               if not result[dev].ports then
+                                                       result[dev].ports = { }
+                                               end
+
+                                               result[dev].id = readfile("/sys/class/net/"..dev.."/bridge/bridge_id")
+                                               result[dev].stp = (readfile("/sys/class/net/"..dev.."/bridge/stp_state") ~= "0")
+                                               result[dev].bridge = true
+                                       end
+
+                                       local opr = readfile("/sys/class/net/"..dev.."/operstate")
+
+                                       result[dev].up = (opr == "up" or opr == "unknown")
+                                       result[dev].type = tonumber(readfile("/sys/class/net/"..dev.."/type"))
+                                       result[dev].name = dev
+
+                                       local mtu = tonumber(readfile("/sys/class/net/"..dev.."/mtu"))
+                                       if mtu and mtu > 0 then
+                                               result[dev].mtu = mtu
+                                       end
+
+                                       local qlen = tonumber(readfile("/sys/class/net/"..dev.."/tx_queue_len"))
+                                       if qlen and qlen > 0 then
+                                               result[dev].qlen = qlen
+                                       end
+
+                                       local master = fs.readlink("/sys/class/net/"..dev.."/master")
+                                       if master then
+                                               result[dev].master = fs.basename(master)
+                                       end
+
+                                       local mac = readfile("/sys/class/net/"..dev.."/address")
+                                       if mac and #mac == 17 then
+                                               result[dev].mac = mac
+                                       end
+                               end
+                       end
+                       return result
+               end
+       },
+
+       boardjson = {
+               call = function(args)
+                       local jsc = require "luci.jsonc"
+                       return jsc.parse(fs.readfile("/etc/board.json") or "")
+               end
+       },
+
+       offload_support = {
+               call = function()
+                       local fs = require "nixio.fs"
+                       return { offload_support = not not fs.access("/sys/module/xt_FLOWOFFLOAD/refcnt") }
+               end
        }
 }
 
@@ -256,6 +333,6 @@ elseif arg[1] == "call" then
        local args = parseInput()
        local method = validateArgs(arg[2], args)
        local result, code = method.call(args)
-       print(json.stringify(result))
+       print((json.stringify(result):gsub("^%[%]$", "{}")))
        os.exit(code or 0)
 end