summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-mod-network/luasrc
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2019-09-12 11:06:38 +0200
committerJo-Philipp Wich <jo@mein.io>2019-09-12 11:09:57 +0200
commit82743b3bd4b4603f2c6b85566d07182cb0f1ce52 (patch)
tree9444cba040a334821e6593c13541792c718084ea /modules/luci-mod-network/luasrc
parent5fd21bc9efedb29ff8376f8043ed2a4b74788d6b (diff)
luci-mod-network: reimplement switch configuration as client side view
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'modules/luci-mod-network/luasrc')
-rw-r--r--modules/luci-mod-network/luasrc/controller/admin/network.lua15
-rw-r--r--modules/luci-mod-network/luasrc/model/cbi/admin_network/vlan.lua389
-rw-r--r--modules/luci-mod-network/luasrc/view/admin_network/switch_status.htm62
3 files changed, 1 insertions, 465 deletions
diff --git a/modules/luci-mod-network/luasrc/controller/admin/network.lua b/modules/luci-mod-network/luasrc/controller/admin/network.lua
index a381bbc61..f8623be93 100644
--- a/modules/luci-mod-network/luasrc/controller/admin/network.lua
+++ b/modules/luci-mod-network/luasrc/controller/admin/network.lua
@@ -18,13 +18,7 @@ function index()
end)
if has_switch then
- page = node("admin", "network", "vlan")
- page.target = cbi("admin_network/vlan")
- page.title = _("Switch")
- page.order = 20
-
- page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
- page.leaf = true
+ entry({"admin", "network", "switch"}, view("network/switch"), _("Switch"), 20)
end
@@ -271,13 +265,6 @@ function wifi_reconnect(radio)
end
end
-function switch_status(switches)
- local s = require "luci.tools.status"
-
- luci.http.prepare_content("application/json")
- luci.http.write_json(s.switch_status(switches))
-end
-
function diag_command(cmd, addr)
if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
luci.http.prepare_content("text/plain")
diff --git a/modules/luci-mod-network/luasrc/model/cbi/admin_network/vlan.lua b/modules/luci-mod-network/luasrc/model/cbi/admin_network/vlan.lua
deleted file mode 100644
index edeb193ef..000000000
--- a/modules/luci-mod-network/luasrc/model/cbi/admin_network/vlan.lua
+++ /dev/null
@@ -1,389 +0,0 @@
--- Copyright 2008 Steven Barth <steven@midlink.org>
--- Copyright 2010-2011 Jo-Philipp Wich <jow@openwrt.org>
--- Licensed to the public under the Apache License 2.0.
-
-m = Map("network", translate("Switch"), translate("The network ports on this device can be combined to several <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s in which computers can communicate directly with each other. <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s are often used to separate different network segments. Often there is by default one Uplink port for a connection to the next greater network like the internet and other ports for a local network."))
-
-local fs = require "nixio.fs"
-local ut = require "luci.util"
-local nw = require "luci.model.network"
-local switches = { }
-
-nw.init(m.uci)
-
-local topologies = nw:get_switch_topologies() or {}
-
-local update_interfaces = function(old_ifname, new_ifname)
- local info = { }
-
- m.uci:foreach("network", "interface", function(section)
- local old_ifnames = section.ifname
- local new_ifnames = { }
- local cur_ifname
- local changed = false
- for cur_ifname in luci.util.imatch(old_ifnames) do
- if cur_ifname == old_ifname then
- new_ifnames[#new_ifnames+1] = new_ifname
- changed = true
- else
- new_ifnames[#new_ifnames+1] = cur_ifname
- end
- end
- if changed then
- m.uci:set("network", section[".name"], "ifname", table.concat(new_ifnames, " "))
-
- info[#info+1] = translatef("Interface %q device auto-migrated from %q to %q.",
- section[".name"], old_ifname, new_ifname)
- end
- end)
-
- if #info > 0 then
- m.message = (m.message and m.message .. "\n" or "") .. table.concat(info, "\n")
- end
-end
-
-local vlan_already_created
-
-m.uci:foreach("network", "switch",
- function(x)
- local sid = x['.name']
- local switch_name = x.name or sid
- local has_vlan = nil
- local has_learn = nil
- local has_vlan4k = nil
- local has_jumbo3 = nil
- local has_mirror = nil
- local min_vid = 0
- local max_vid = 16
- local num_vlans = 16
-
- local switch_title
- local enable_vlan4k = false
-
- local topo = topologies[switch_name]
-
- if not topo then
- m.message = translatef("Switch %q has an unknown topology - the VLAN settings might not be accurate.", switch_name)
- topo = {
- ports = {
- { num = 0, label = "Port 1" },
- { num = 1, label = "Port 2" },
- { num = 2, label = "Port 3" },
- { num = 3, label = "Port 4" },
- { num = 4, label = "Port 5" },
- { num = 5, label = "CPU (eth0)", tagged = false }
- }
- }
- end
-
- -- Parse some common switch properties from swconfig help output.
- local swc = io.popen("swconfig dev %s help 2>/dev/null" % ut.shellquote(switch_name))
- if swc then
-
- local is_port_attr = false
- local is_vlan_attr = false
-
- 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
- switch_title = line:match("^switch%d: %w+%((.-)%)")
- num_vlans = tonumber(line:match("vlans: (%d+)")) or 16
- min_vid = 1
-
- elseif line:match(": pvid") or line:match(": tag") or line:match(": vid") then
- if is_vlan_attr then has_vlan4k = line:match(": (%w+)") end
-
- elseif line:match(": enable_vlan4k") then
- enable_vlan4k = true
-
- elseif line:match(": enable_vlan") then
- has_vlan = "enable_vlan"
-
- elseif line:match(": enable_learning") then
- has_learn = "enable_learning"
-
- elseif line:match(": enable_mirror_rx") then
- has_mirror = "enable_mirror_rx"
-
- elseif line:match(": max_length") then
- has_jumbo3 = "max_length"
- end
- end
-
- swc:close()
- end
-
-
- -- Switch properties
- s = m:section(NamedSection, x['.name'], "switch",
- switch_title and translatef("Switch %q (%s)", switch_name, switch_title)
- or translatef("Switch %q", switch_name))
-
- s.addremove = false
-
- if has_vlan then
- s:option(Flag, has_vlan, translate("Enable VLAN functionality"))
- end
-
- if has_learn then
- x = s:option(Flag, has_learn, translate("Enable learning and aging"))
- x.default = x.enabled
- end
-
- if has_jumbo3 then
- x = s:option(Flag, has_jumbo3, translate("Enable Jumbo Frame passthrough"))
- x.enabled = "3"
- x.rmempty = true
- end
-
- -- Does this switch support port mirroring?
- if has_mirror then
- s:option(Flag, "enable_mirror_rx", translate("Enable mirroring of incoming packets"))
- s:option(Flag, "enable_mirror_tx", translate("Enable mirroring of outgoing packets"))
-
- local sp = s:option(ListValue, "mirror_source_port", translate("Mirror source port"))
- local mp = s:option(ListValue, "mirror_monitor_port", translate("Mirror monitor port"))
-
- sp:depends("enable_mirror_tx", "1")
- sp:depends("enable_mirror_rx", "1")
-
- mp:depends("enable_mirror_tx", "1")
- mp:depends("enable_mirror_rx", "1")
-
- local _, pt
- for _, pt in ipairs(topo.ports) do
- sp:value(pt.num, pt.label)
- mp:value(pt.num, pt.label)
- end
- end
-
- -- VLAN table
- s = m:section(TypedSection, "switch_vlan",
- switch_title and translatef("VLANs on %q (%s)", switch_name, switch_title)
- or translatef("VLANs on %q", switch_name))
-
- s.template = "cbi/tblsection"
- s.addremove = true
- s.anonymous = true
-
- -- Filter by switch
- s.filter = function(self, section)
- local device = m:get(section, "device")
- return (device and device == switch_name)
- end
-
- -- Override cfgsections callback to enforce row ordering by vlan id.
- s.cfgsections = function(self)
- local osections = TypedSection.cfgsections(self)
- local sections = { }
- local section
-
- for _, section in luci.util.spairs(
- osections,
- function(a, b)
- return (tonumber(m:get(osections[a], has_vlan4k or "vlan")) or 9999)
- < (tonumber(m:get(osections[b], has_vlan4k or "vlan")) or 9999)
- end
- ) do
- sections[#sections+1] = section
- end
-
- return sections
- end
-
- -- When creating a new vlan, preset it with the highest found vid + 1.
- s.create = function(self, section, origin)
- -- VLAN has already been created for another switch
- if vlan_already_created then
- return
-
- -- VLAN add button was pressed in an empty VLAN section so only
- -- accept the create event if our switch is without existing VLANs
- elseif origin == "" then
- local is_empty_switch = true
-
- m.uci:foreach("network", "switch_vlan",
- function(s)
- if s.device == switch_name then
- is_empty_switch = false
- return false
- end
- end)
-
- if not is_empty_switch then
- return
- end
-
- -- VLAN was created for another switch
- elseif m:get(origin, "device") ~= switch_name then
- return
- end
-
- local sid = TypedSection.create(self, section)
-
- local max_nr = 0
- local max_id = 0
-
- m.uci:foreach("network", "switch_vlan",
- function(s)
- if s.device == switch_name then
- local nr = tonumber(s.vlan)
- local id = has_vlan4k and tonumber(s[has_vlan4k])
- if nr ~= nil and nr > max_nr then max_nr = nr end
- if id ~= nil and id > max_id then max_id = id end
- end
- end)
-
- m:set(sid, "device", switch_name)
- m:set(sid, "vlan", max_nr + 1)
-
- if has_vlan4k then
- m:set(sid, has_vlan4k, max_id + 1)
- end
-
- vlan_already_created = true
-
- return sid
- end
-
-
- local port_opts = { }
- local untagged = { }
-
- -- Parse current tagging state from the "ports" option.
- local portvalue = function(self, section)
- local pt
- for pt in (m:get(section, "ports") or ""):gmatch("%w+") do
- local pc, tu = pt:match("^(%d+)([tu]*)")
- if pc == self.option then return (#tu > 0) and tu or "u" end
- end
- return ""
- end
-
- -- Validate port tagging. Ensure that a port is only untagged once,
- -- bail out if not.
- local portvalidate = function(self, value, section)
- -- ensure that the ports appears untagged only once
- if value == "u" then
- if not untagged[self.option] then
- untagged[self.option] = true
- else
- return nil,
- translatef("%s is untagged in multiple VLANs!", self.title)
- end
- end
- return value
- end
-
-
- local vid = s:option(Value, has_vlan4k or "vlan", "VLAN ID")
- local mx_vid = has_vlan4k and 4094 or (num_vlans - 1)
-
- vid.rmempty = false
- vid.forcewrite = true
- vid.vlan_used = { }
- vid.datatype = "and(uinteger,range("..min_vid..","..mx_vid.."))"
-
- -- Validate user provided VLAN ID, make sure its within the bounds
- -- allowed by the switch.
- vid.validate = function(self, value, section)
- local v = tonumber(value)
- local m = has_vlan4k and 4094 or (num_vlans - 1)
- if v ~= nil and v >= min_vid and v <= m then
- if not self.vlan_used[v] then
- self.vlan_used[v] = true
- return value
- else
- return nil,
- translatef("Invalid VLAN ID given! Only unique IDs are allowed")
- end
- else
- return nil,
- translatef("Invalid VLAN ID given! Only IDs between %d and %d are allowed.", min_vid, m)
- end
- end
-
- -- When writing the "vid" or "vlan" option, serialize the port states
- -- as well and write them as "ports" option to uci.
- vid.write = function(self, section, new_vid)
- local o
- local p = { }
- for _, o in ipairs(port_opts) do
- local new_tag = o:formvalue(section)
- if new_tag == "t" then
- p[#p+1] = o.option .. new_tag
- elseif new_tag == "u" then
- p[#p+1] = o.option
- end
-
- if o.info and o.info.device then
- local old_tag = o:cfgvalue(section)
- local old_vid = self:cfgvalue(section)
- if old_tag ~= new_tag or old_vid ~= new_vid then
- local old_ifname = (old_tag == "u") and o.info.device
- or "%s.%s" %{ o.info.device, old_vid }
-
- local new_ifname = (new_tag == "u") and o.info.device
- or "%s.%s" %{ o.info.device, new_vid }
-
- if old_ifname ~= new_ifname then
- update_interfaces(old_ifname, new_ifname)
- end
- end
- end
- end
-
- if enable_vlan4k then
- m:set(sid, "enable_vlan4k", "1")
- end
-
- m:set(section, "ports", table.concat(p, " "))
- return Value.write(self, section, new_vid)
- end
-
- -- Fallback to "vlan" option if "vid" option is supported but unset.
- vid.cfgvalue = function(self, section)
- return m:get(section, has_vlan4k or "vlan")
- or m:get(section, "vlan")
- end
-
- local _, pt
- for _, pt in ipairs(topo.ports) do
- local po = s:option(ListValue, tostring(pt.num), pt.label)
-
- po:value("", translate("off"))
-
- if not pt.tagged then
- po:value("u", translate("untagged"))
- end
-
- po:value("t", translate("tagged"))
-
- po.cfgvalue = portvalue
- po.validate = portvalidate
- po.write = function() end
- po.info = pt
-
- port_opts[#port_opts+1] = po
- end
-
- table.sort(port_opts, function(a, b) return a.option < b.option end)
- switches[#switches+1] = switch_name
- end
-)
-
--- Switch status template
-s = m:section(SimpleSection)
-s.template = "admin_network/switch_status"
-s.switches = switches
-
-return m
diff --git a/modules/luci-mod-network/luasrc/view/admin_network/switch_status.htm b/modules/luci-mod-network/luasrc/view/admin_network/switch_status.htm
deleted file mode 100644
index 6e741b419..000000000
--- a/modules/luci-mod-network/luasrc/view/admin_network/switch_status.htm
+++ /dev/null
@@ -1,62 +0,0 @@
-<script type="text/javascript">//<![CDATA[
- var switches = [ '<%=table.concat(self.switches, "', '")%>' ],
- tables = document.querySelectorAll('.cbi-section-table');
-
- function add_status_row(table) {
- var first_row = table.querySelector('.cbi-section-table-row');
- if (first_row.classList.contains('port-status'))
- return first_row;
-
- var status_row = first_row.parentNode.insertBefore(
- E('div', { 'class': first_row.className }), first_row);
-
- first_row.querySelectorAll('.td').forEach(function(td) {
- status_row.appendChild(td.cloneNode(false));
- status_row.lastElementChild.removeAttribute('data-title');
- });
-
- status_row.firstElementChild.innerHTML = '<%:Port status:%>';
- status_row.classList.add('port-status') ;
-
- return status_row;
- }
-
- XHR.poll(-1, '<%=url('admin/network/switch_status')%>/' + switches.join(','), null,
- function(x, st)
- {
- for (var i = 0; i < switches.length; i++)
- {
- var ports = st[switches[i]];
- var tr = add_status_row(tables[i]);
-
- if (tr && ports && ports.length)
- {
- for (var j = 0; j < ports.length; j++)
- {
- var th = tr.querySelector('[data-name="%d"]'.format(j));
-
- if (!th)
- continue;
-
- if (ports[j].link)
- {
- th.innerHTML = String.format(
- '<small><img src="<%=resource%>/icons/port_up.png" />' +
- '<br />%d<%:baseT%><br />%s</small>',
- ports[j].speed, ports[j].duplex
- ? '<%:full-duplex%>' : '<%:half-duplex%>'
- );
- }
- else
- {
- th.innerHTML = String.format(
- '<small><img src="<%=resource%>/icons/port_down.png" />' +
- '<br /><%:no link%></small>'
- );
- }
- }
- }
- }
- }
- );
-//]]></script>