luci-base: add luci/getSwconfigFeatures and luci/getSwconfigPortState
authorJo-Philipp Wich <jo@mein.io>
Thu, 12 Sep 2019 09:01:19 +0000 (11:01 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 12 Sep 2019 09:09:57 +0000 (11:09 +0200)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/root/usr/libexec/rpcd/luci
modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json

index 850b159acfa8bfa6d57606c3d38874c2da93f6da..99c172a96b780cc6893474984ef28010aa4c9303 100755 (executable)
@@ -468,6 +468,113 @@ local methods = {
 
                        return rv
                end
+       },
+
+       getSwconfigFeatures = {
+               args = { switch = "switch0" },
+               call = function(args)
+                       local util = require "luci.util"
+
+                       -- Parse some common switch properties from swconfig help output.
+                       local swc, err = io.popen("swconfig dev %s help 2>/dev/null" % util.shellquote(args.switch))
+                       if swc then
+                               local is_port_attr = false
+                               local is_vlan_attr = false
+                               local rv = {}
+
+                               while true do
+                                       local line = swc:read("*l")
+                                       if not line then break end
+
+                                       if line:match("^%s+%-%-vlan") then
+                                               is_vlan_attr = true
+
+                                       elseif line:match("^%s+%-%-port") then
+                                               is_vlan_attr = false
+                                               is_port_attr = true
+
+                                       elseif line:match("cpu @") then
+                                               rv.switch_title = line:match("^switch%d: %w+%((.-)%)")
+                                               rv.num_vlans    = tonumber(line:match("vlans: (%d+)")) or 16
+                                               rv.min_vid      = 1
+
+                                       elseif line:match(": pvid") or line:match(": tag") or line:match(": vid") then
+                                               if is_vlan_attr then rv.vid_option = line:match(": (%w+)") end
+
+                                       elseif line:match(": enable_vlan4k") then
+                                               rv.vlan4k_option = "enable_vlan4k"
+
+                                       elseif line:match(": enable_vlan") then
+                                               rv.vlan_option = "enable_vlan"
+
+                                       elseif line:match(": enable_learning") then
+                                               rv.learning_option = "enable_learning"
+
+                                       elseif line:match(": enable_mirror_rx") then
+                                               rv.mirror_option = "enable_mirror_rx"
+
+                                       elseif line:match(": max_length") then
+                                               rv.jumbo_option = "max_length"
+                                       end
+                               end
+
+                               swc:close()
+
+                               if not next(rv) then
+                                       return { error = "No such switch" }
+                               end
+
+                               return rv
+                       else
+                               return { error = err }
+                       end
+               end
+       },
+
+       getSwconfigPortState = {
+               args = { switch = "switch0" },
+               call = function(args)
+                       local util = require "luci.util"
+
+                       local swc, err = io.popen("swconfig dev %s show 2>/dev/null" % util.shellquote(args.switch))
+                       if swc then
+                               local ports = { }
+
+                               while true do
+                                       local line = swc:read("*l")
+                                       if not line then break end
+
+                                       local port, up = line:match("port:(%d+) link:(%w+)")
+                                       if port then
+                                               local speed  = line:match(" speed:(%d+)")
+                                               local duplex = line:match(" (%w+)-duplex")
+                                               local txflow = line:match(" (txflow)")
+                                               local rxflow = line:match(" (rxflow)")
+                                               local auto   = line:match(" (auto)")
+
+                                               ports[#ports+1] = {
+                                                       port   = tonumber(port) or 0,
+                                                       speed  = tonumber(speed) or 0,
+                                                       link   = (up == "up"),
+                                                       duplex = (duplex == "full"),
+                                                       rxflow = (not not rxflow),
+                                                       txflow = (not not txflow),
+                                                       auto   = (not not auto)
+                                               }
+                                       end
+                               end
+
+                               swc:close()
+
+                               if not next(ports) then
+                                       return { error = "No such switch" }
+                               end
+
+                               return { result = ports }
+                       else
+                               return { error = err }
+                       end
+               end
        }
 }
 
index 1952a7c3ae014f08a351f7a192610fa7afdc7adc..a0852eaec575d3f93873a3db190dec4da8fc42dc 100644 (file)
@@ -28,7 +28,7 @@
                        "ubus": {
                                "file": [ "list", "read", "stat" ],
                                "iwinfo": [ "assoclist", "freqlist", "txpowerlist", "countrylist" ],
-                               "luci": [ "getBoardJSON", "getDUIDHints", "getHostHints", "getIfaddrs", "getInitList", "getLocaltime", "getTimezones", "getDHCPLeases", "getLEDs", "getNetworkDevices", "getUSBDevices", "getWirelessDevices" ],
+                               "luci": [ "getBoardJSON", "getDUIDHints", "getHostHints", "getIfaddrs", "getInitList", "getLocaltime", "getTimezones", "getDHCPLeases", "getLEDs", "getNetworkDevices", "getUSBDevices", "getWirelessDevices", "getSwconfigFeatures", "getSwconfigPortState" ],
                                "network.device": [ "status" ],
                                "network.interface": [ "dump" ],
                                "network": [ "get_proto_handlers" ],