luci-mod-admin-full: auto-migrate ifnames when changing VLAN configuration

This change extends the switch VLAN configuration page to automatically
adjust interface ifname options when altering VLAN settings.

For example "eth0" is changed to "eth0.1" when a previously untagged LAN
VLAN is switched to tagged on the CPU port and vice versa.

Notifications are displayed in the page header if an auto migration was
performed.

This change should make the switch configuration more user friendly and
less prone to soft bricking.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2017-05-29 08:45:38 +02:00
parent ee6110b3ac
commit aa2b1cdc2c

View file

@ -12,6 +12,35 @@ nw.init(m.uci)
local topologies = nw:get_switch_topologies() or {} 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 = m.uci:get("network", section[".name"], "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
m.uci:foreach("network", "switch", m.uci:foreach("network", "switch",
function(x) function(x)
local sid = x['.name'] local sid = x['.name']
@ -259,17 +288,32 @@ m.uci:foreach("network", "switch",
-- When writing the "vid" or "vlan" option, serialize the port states -- When writing the "vid" or "vlan" option, serialize the port states
-- as well and write them as "ports" option to uci. -- as well and write them as "ports" option to uci.
vid.write = function(self, section, value) vid.write = function(self, section, new_vid)
local o local o
local p = { } local p = { }
for _, o in ipairs(port_opts) do for _, o in ipairs(port_opts) do
local v = o:formvalue(section) local new_tag = o:formvalue(section)
if v == "t" then if new_tag == "t" then
p[#p+1] = o.option .. v p[#p+1] = o.option .. new_tag
elseif v == "u" then elseif new_tag == "u" then
p[#p+1] = o.option p[#p+1] = o.option
end 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 end
if enable_vlan4k then if enable_vlan4k then
@ -277,7 +321,7 @@ m.uci:foreach("network", "switch",
end end
m:set(section, "ports", table.concat(p, " ")) m:set(section, "ports", table.concat(p, " "))
return Value.write(self, section, value) return Value.write(self, section, new_vid)
end end
-- Fallback to "vlan" option if "vid" option is supported but unset. -- Fallback to "vlan" option if "vid" option is supported but unset.
@ -301,6 +345,7 @@ m.uci:foreach("network", "switch",
po.cfgvalue = portvalue po.cfgvalue = portvalue
po.validate = portvalidate po.validate = portvalidate
po.write = function() end po.write = function() end
po.info = pt
port_opts[#port_opts+1] = po port_opts[#port_opts+1] = po
end end