treewide: use interface roles as basis for network configuration

With the new role-based interface configuration, it would be better to
rename the wan/wan6 interfaces to uplink/uplink6, but that would cause
unnecessary churn for the firewall configuration, so it is left for a
later update.

As all interfaces with the 'uplink' role are in the br-wan bridge, it is
not possible to assign these to the 'mesh' role independently - instead,
br-wan is added as a mesh interface as soon as a single interface has
both the 'uplink' and 'mesh' roles. The UCI section for this
configuration is now called 'mesh_uplink' instead of 'mesh_wan'.

For all interfaces that have the 'mesh', but not the 'uplink' role a
second configuration 'mesh_other' is created. If there is more than one
such interface, all these interfaces are bridged as well (creating a
bridge 'br-mesh_other'). This replaces the 'mesh_lan' section with its
optional 'br-mesh_lan' bridge, but can also include interfaces that were
not considered "LAN" when interfaces roles are modified (via site.conf
or manually).
This commit is contained in:
Matthias Schiffer 2022-01-23 14:43:35 +01:00
parent 4b8251c988
commit c779d12369
No known key found for this signature in database
GPG Key ID: 16EF3F64CB201D9C
8 changed files with 85 additions and 74 deletions

View File

@ -6,12 +6,8 @@ local util = require 'gluon.util'
local uci = require('simple-uci').cursor() local uci = require('simple-uci').cursor()
local interfaces = { 'local-port' } local interfaces = util.get_role_interfaces(uci, 'client', true)
if sysconfig.lan_ifname and uci:get_bool('network', 'mesh_lan', 'disabled') then util.add_to_set(interfaces, 'local-port')
for lanif in sysconfig.lan_ifname:gmatch('%S+') do
util.add_to_set(interfaces, lanif)
end
end
uci:section('network', 'interface', 'client', { uci:section('network', 'interface', 'client', {
type = 'bridge', type = 'bridge',

View File

@ -1,7 +1,7 @@
#!/usr/bin/lua #!/usr/bin/lua
local uci = require('simple-uci').cursor() local uci = require('simple-uci').cursor()
local sysconfig = require 'gluon.sysconfig' local util = require 'gluon.util'
local wan = uci:get_all('network_gluon-old', 'wan') or {} local wan = uci:get_all('network_gluon-old', 'wan') or {}
local wan6 = uci:get_all('network_gluon-old', 'wan6') or {} local wan6 = uci:get_all('network_gluon-old', 'wan6') or {}
@ -18,7 +18,7 @@ uci:section('network', 'interface', 'wan', {
ipaddr = wan.ipaddr, ipaddr = wan.ipaddr,
netmask = wan.netmask, netmask = wan.netmask,
gateway = wan.gateway, gateway = wan.gateway,
ifname = sysconfig.wan_ifname, ifname = util.get_role_interfaces(uci, 'uplink'),
type = 'bridge', type = 'bridge',
igmp_snooping = true, igmp_snooping = true,
multicast_querier = false, multicast_querier = false,

View File

@ -0,0 +1,48 @@
#!/usr/bin/lua
local site = require 'gluon.site'
local uci = require('simple-uci').cursor()
local util = require 'gluon.util'
local mesh_interfaces = util.get_role_interfaces(uci, 'mesh')
local uplink_interfaces = util.get_role_interfaces(uci, 'uplink')
local mesh_interfaces_uplink = {}
local mesh_interfaces_other = {}
for _, iface in ipairs(mesh_interfaces) do
if util.contains(uplink_interfaces, iface) then
table.insert(mesh_interfaces_uplink, iface)
else
table.insert(mesh_interfaces_other, iface)
end
end
if #mesh_interfaces_uplink > 0 then
uci:section('network', 'interface', 'mesh_uplink', {
ifname = 'br-wan',
proto = 'gluon_wired',
index = 0,
vxlan = site.mesh.vxlan(true),
})
end
if #mesh_interfaces_other > 0 then
local iftype, ifname
if #mesh_interfaces_other == 1 then
ifname = mesh_interfaces_other[1]
else
iftype = 'bridge'
ifname = mesh_interfaces_other
end
uci:section('network', 'interface', 'mesh_other', {
ifname = ifname,
type = iftype,
igmp_snooping = false,
proto = 'gluon_wired',
index = 4,
vxlan = site.mesh.vxlan(true),
})
end
uci:save('network')

View File

@ -1,25 +0,0 @@
#!/usr/bin/lua
local site = require 'gluon.site'
local uci = require('simple-uci').cursor()
local disabled = uci:get('network_gluon-old', 'mesh_wan', 'disabled')
if disabled == nil then
disabled = not site.mesh_on_wan(false)
end
local transitive = uci:get('network_gluon-old', 'mesh_wan', 'transitive')
if transitive == nil then
transitive = true
end
uci:section('network', 'interface', 'mesh_wan', {
ifname = 'br-wan',
proto = 'gluon_wired',
index = 0,
vxlan = site.mesh.vxlan(true),
disabled = disabled,
transitive = transitive,
})
uci:save('network')

View File

@ -1,38 +0,0 @@
#!/usr/bin/lua
local site = require 'gluon.site'
local sysconfig = require 'gluon.sysconfig'
local uci = require('simple-uci').cursor()
if not sysconfig.lan_ifname then
os.exit(0)
end
local type
if sysconfig.lan_ifname:match(' ') then
type = 'bridge'
end
local disabled = uci:get('network_gluon-old', 'mesh_lan', 'disabled')
if disabled == nil then
disabled = not site.mesh_on_lan(false)
end
local transitive = uci:get('network_gluon-old', 'mesh_lan', 'transitive')
if transitive == nil then
transitive = true
end
uci:section('network', 'interface', 'mesh_lan', {
ifname = sysconfig.lan_ifname,
type = type,
igmp_snooping = false,
proto = 'gluon_wired',
index = 4,
vxlan = site.mesh.vxlan(true),
disabled = disabled,
transitive = transitive,
})
uci:save('network')

View File

@ -86,9 +86,9 @@ local wired_mesh_ifaces = {}
uci:foreach('network', 'interface', uci:foreach('network', 'interface',
function(iface) function(iface)
-- Select all interfaces with proto gluon_wired except for -- Select all interfaces with proto gluon_wired except for
-- mesh_wan into this zone, as mesh_wan is the same -- mesh_uplink into this zone, as mesh_uplink is the same
-- interface as wan, which has its own zone -- interface as wan, which has its own zone
if iface['proto'] == 'gluon_wired' and iface['.name'] ~= 'mesh_wan' then if iface['proto'] == 'gluon_wired' and iface['.name'] ~= 'mesh_uplink' then
table.insert(wired_mesh_ifaces, iface['.name']) table.insert(wired_mesh_ifaces, iface['.name'])
end end
end end

View File

@ -138,6 +138,34 @@ function M.get_mesh_devices(uconn)
return devices return devices
end end
-- Returns a list of all interfaces with a given role
--
-- If exclusive is set to true, only interfaces that have no other role
-- are returned; this is used to ensure that the client role is not active
-- at the same time as any other role
function M.get_role_interfaces(uci, role, exclusive)
local ret = {}
local function add(name)
-- Interface names with a / prefix refer to sysconfig interfaces
-- (lan_ifname/wan_ifname/single_ifname)
if string.sub(name, 1, 1) == '/' then
name = sysconfig[string.sub(name, 2) .. '_ifname'] or ''
end
for iface in string.gmatch(name, '%S+') do
M.add_to_set(ret, iface)
end
end
uci:foreach('gluon', 'interface', function(s)
if M.contains(s.role, role) and (not exclusive or #s.role == 1) then
add(s.name)
end
end)
return ret
end
-- Safe glob: returns an empty table when the glob fails because of -- Safe glob: returns an empty table when the glob fails because of
-- a non-existing path -- a non-existing path
function M.glob(pattern) function M.glob(pattern)

View File

@ -9,5 +9,7 @@ local uci = require('simple-uci').cursor()
if not site.mesh.vxlan(true) then if not site.mesh.vxlan(true) then
uci:set('network', 'wan', 'macaddr', util.generate_mac(0)) uci:set('network', 'wan', 'macaddr', util.generate_mac(0))
end end
uci:set('network', 'mesh_lan', 'macaddr', util.generate_mac(4)) if uci:get('network', 'mesh_other') then
uci:set('network', 'mesh_other', 'macaddr', util.generate_mac(4))
end
uci:save('network') uci:save('network')