Merge pull request #2372 from freifunk-gluon/uci-regen
Regenerate network and system UCI configs on every reconfigure, switch to role-based interface configuration
This commit is contained in:
commit
a3203b26c4
@ -1,5 +1,5 @@
|
|||||||
WAN support
|
Uplink support
|
||||||
===========
|
==============
|
||||||
|
|
||||||
As the WAN port of a node will be connected to a user's private network, it
|
As the WAN port of a node will be connected to a user's private network, it
|
||||||
is essential that the node only uses the WAN when it is absolutely necessary.
|
is essential that the node only uses the WAN when it is absolutely necessary.
|
||||||
@ -11,11 +11,12 @@ There are two cases in which the WAN port is used:
|
|||||||
After the VPN connection has been established, the node should be able to reach
|
After the VPN connection has been established, the node should be able to reach
|
||||||
the mesh's DNS servers and use these for all other name resolution.
|
the mesh's DNS servers and use these for all other name resolution.
|
||||||
|
|
||||||
If the device does not feature a WAN port, the LAN port is configured as WAN port.
|
If a device has only a single Ethernet port (or group of ports), it will be
|
||||||
In case such a device has multiple LAN ports, all these can be used as WAN.
|
used as an uplink port even when it is not labelled as "WAN" by default. This
|
||||||
Devices, which feature a "hybrid" port (labelled as WAN/LAN), this port is used as WAN.
|
behavior can be controlled using the ``interfaces.single.default_roles``
|
||||||
|
site.conf option. It is also possible to alter the interface assignment after
|
||||||
This behavior can be reversed using the ``single_as_lan`` site.conf option.
|
installation by modifying ``/etc/config/gluon`` and running
|
||||||
|
``gluon-reconfigure``.
|
||||||
|
|
||||||
Routing tables
|
Routing tables
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
@ -130,9 +130,7 @@ site.conf only variables
|
|||||||
- authorized_keys
|
- authorized_keys
|
||||||
- default_domain
|
- default_domain
|
||||||
- poe_passthrough
|
- poe_passthrough
|
||||||
- mesh_on_wan
|
- interfaces.*.default_roles
|
||||||
- mesh_on_lan
|
|
||||||
- single_as_lan
|
|
||||||
- setup_mode.skip
|
- setup_mode.skip
|
||||||
- autoupdater.branch
|
- autoupdater.branch
|
||||||
- mesh_vpn.enabled
|
- mesh_vpn.enabled
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
Private WLAN
|
Private WLAN
|
||||||
============
|
============
|
||||||
|
|
||||||
It is possible to set up a private WLAN that bridges the WAN port and is separated from the mesh network.
|
It is possible to set up a private WLAN that bridges the uplink port and is separated from the mesh network.
|
||||||
Please note that you should not enable ``mesh_on_wan`` simultaneously.
|
Please note that you should not enable Wired Mesh on the uplink port at the same time.
|
||||||
|
|
||||||
The private WLAN is encrypted using WPA2 by default. On devices with enough flash and a supported radio,
|
The private WLAN is encrypted using WPA2 by default. On devices with enough flash and a supported radio,
|
||||||
WPA3 or WPA2/WPA3 mixed-mode can be used instead of WPA2. For this to work, the ``wireless-encryption-wpa3``
|
WPA3 or WPA2/WPA3 mixed-mode can be used instead of WPA2. For this to work, the ``wireless-encryption-wpa3``
|
||||||
|
@ -50,8 +50,8 @@ Configuration
|
|||||||
Both Mesh-on-WAN and Mesh-on-LAN can be configured on the "Network" page
|
Both Mesh-on-WAN and Mesh-on-LAN can be configured on the "Network" page
|
||||||
of the *Advanced settings* (if the package ``gluon-web-network`` is installed).
|
of the *Advanced settings* (if the package ``gluon-web-network`` is installed).
|
||||||
|
|
||||||
It is also possible to enable Mesh-on-WAN and Mesh-on-LAN by default by
|
It is also possible to enable Mesh-on-WAN and Mesh-on-LAN by default by adding
|
||||||
adding ``mesh_on_wan = true`` and ``mesh_on_lan = true`` to ``site.conf``.
|
the ``mesh`` role to the ``interfaces.*.default_roles`` options in site.conf.
|
||||||
|
|
||||||
Commandline
|
Commandline
|
||||||
===========
|
===========
|
||||||
|
@ -39,7 +39,7 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
|
|||||||
dev/hardware
|
dev/hardware
|
||||||
dev/packages
|
dev/packages
|
||||||
dev/upgrade
|
dev/upgrade
|
||||||
dev/wan
|
dev/uplink
|
||||||
dev/mac_addresses
|
dev/mac_addresses
|
||||||
dev/site_library
|
dev/site_library
|
||||||
dev/build
|
dev/build
|
||||||
|
@ -399,17 +399,49 @@ mesh_vpn
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh_on_wan \: optional
|
interfaces \: optional
|
||||||
Enables the mesh on the WAN port (``true`` or ``false``).
|
Default setup for Ethernet ports.
|
||||||
::
|
::
|
||||||
|
|
||||||
mesh_on_wan = true,
|
interfaces = {
|
||||||
|
lan = {
|
||||||
|
default_roles = { 'client', 'mesh' },
|
||||||
|
},
|
||||||
|
wan = {
|
||||||
|
default_roles = { 'uplink', 'mesh' },
|
||||||
|
},
|
||||||
|
single = {
|
||||||
|
default_roles = { 'uplink', 'mesh' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
mesh_on_lan \: optional
|
For devices that have two distinct Ethernet ports or port groups (often
|
||||||
Enables the mesh on the LAN port (``true`` or ``false``).
|
labelled WAN and LAN), the ``lan`` and ``wan`` sections are used. When there
|
||||||
::
|
is only one port (group), ``single`` is used instead.
|
||||||
|
|
||||||
mesh_on_lan = true,
|
Available interface roles:
|
||||||
|
|
||||||
|
- ``client``: Port allows regular clients to connect to the mesh
|
||||||
|
- ``uplink``: Port is used to establish Mesh VPN connections
|
||||||
|
- ``mesh``: Wired meshing to another Gluon or Gluon-compatible node
|
||||||
|
|
||||||
|
The ``client`` role requires exclusive control over an interface. When
|
||||||
|
the ``client`` role is assigned to an interface at the same time as other
|
||||||
|
roles (like ``'client', 'mesh'`` in the above example), the other roles take
|
||||||
|
precedence (enabling ``mesh``, but not ``client`` in the example).
|
||||||
|
|
||||||
|
Such a default configuration still fulfills a purpose (and is in fact the
|
||||||
|
recommended way to enable "Mesh-on-LAN" by default): The "LAN interface
|
||||||
|
meshing" checkbox in the advanced network settings will only add or remove
|
||||||
|
the ``mesh`` role, so the ``client`` role must already be in the configuration
|
||||||
|
to make the LAN port a regular client interface when the checkbox is disabled.
|
||||||
|
|
||||||
|
All interface settings are optional. If unset, the following defaults are
|
||||||
|
used:
|
||||||
|
|
||||||
|
- ``lan``: ``{ 'client' }``
|
||||||
|
- ``wan``: ``{ 'uplink' }``
|
||||||
|
- ``single``: Same as ``wan``
|
||||||
|
|
||||||
poe_passthrough \: optional
|
poe_passthrough \: optional
|
||||||
Enable PoE passthrough by default on hardware with such a feature.
|
Enable PoE passthrough by default on hardware with such a feature.
|
||||||
|
@ -6,26 +6,9 @@ local util = require 'gluon.util'
|
|||||||
local uci = require('simple-uci').cursor()
|
local uci = require('simple-uci').cursor()
|
||||||
|
|
||||||
|
|
||||||
local interfaces = uci:get('network', 'client', 'ifname') or {}
|
local interfaces = util.get_role_interfaces(uci, 'client', true)
|
||||||
|
|
||||||
if type(interfaces) == 'string' then
|
|
||||||
local ifname = interfaces
|
|
||||||
interfaces = {}
|
|
||||||
for iface in ifname:gmatch('%S+') do
|
|
||||||
util.add_to_set(interfaces, iface)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if sysconfig.lan_ifname and uci:get_bool('network', 'mesh_lan', 'disabled') then
|
|
||||||
for lanif in sysconfig.lan_ifname:gmatch('%S+') do
|
|
||||||
util.add_to_set(interfaces, lanif)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
util.add_to_set(interfaces, 'local-port')
|
util.add_to_set(interfaces, 'local-port')
|
||||||
|
|
||||||
|
|
||||||
uci:delete('network', 'client')
|
|
||||||
uci:section('network', 'interface', 'client', {
|
uci:section('network', 'interface', 'client', {
|
||||||
type = 'bridge',
|
type = 'bridge',
|
||||||
ifname = interfaces,
|
ifname = interfaces,
|
||||||
|
@ -10,7 +10,6 @@ local uci = require('simple-uci').cursor()
|
|||||||
local next_node = site.next_node({})
|
local next_node = site.next_node({})
|
||||||
|
|
||||||
|
|
||||||
uci:delete('network', 'local_node_dev')
|
|
||||||
uci:section('network', 'device', 'local_node_dev', {
|
uci:section('network', 'device', 'local_node_dev', {
|
||||||
type = 'veth',
|
type = 'veth',
|
||||||
name = 'local-node',
|
name = 'local-node',
|
||||||
@ -31,7 +30,6 @@ if next_node.ip6 then
|
|||||||
ip6 = next_node.ip6 .. '/128'
|
ip6 = next_node.ip6 .. '/128'
|
||||||
end
|
end
|
||||||
|
|
||||||
uci:delete('network', 'local_node')
|
|
||||||
uci:section('network', 'interface', 'local_node', {
|
uci:section('network', 'interface', 'local_node', {
|
||||||
ifname = 'local-node',
|
ifname = 'local-node',
|
||||||
proto = 'static',
|
proto = 'static',
|
||||||
|
@ -74,6 +74,11 @@ need_string_match(in_domain({'next_node', 'ip4'}), '^%d+.%d+.%d+.%d+$', false)
|
|||||||
|
|
||||||
need_boolean(in_domain({'mesh', 'vxlan'}), false)
|
need_boolean(in_domain({'mesh', 'vxlan'}), false)
|
||||||
|
|
||||||
need_boolean(in_site({'mesh_on_wan'}), false)
|
local interfaces_roles = {'client', 'uplink', 'mesh'}
|
||||||
need_boolean(in_site({'mesh_on_lan'}), false)
|
for _, config in ipairs({'wan', 'lan', 'single'}) do
|
||||||
need_boolean(in_site({'single_as_lan'}), false)
|
need_array_of(in_site({'interfaces', config, 'default_roles'}), interfaces_roles, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
obsolete({'mesh_on_wan'}, 'Use interfaces.wan.default_roles.')
|
||||||
|
obsolete({'mesh_on_lan'}, 'Use interfaces.lan.default_roles.')
|
||||||
|
obsolete({'single_as_lan'}, 'Use interfaces.single.default_roles.')
|
||||||
|
23
package/gluon-core/files/lib/gluon/upgrade/001-reset-uci
Executable file
23
package/gluon-core/files/lib/gluon/upgrade/001-reset-uci
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
NETWORK_CFG='/etc/config/network'
|
||||||
|
NETWORK_SAVED="${NETWORK_CFG}_gluon-old"
|
||||||
|
|
||||||
|
SYSTEM_CFG='/etc/config/system'
|
||||||
|
SYSTEM_SAVED="${SYSTEM_CFG}_gluon-old"
|
||||||
|
|
||||||
|
# Make sure everything is saved before we move away the config files
|
||||||
|
uci commit
|
||||||
|
|
||||||
|
# Save old configs (unless there is already a saved config,
|
||||||
|
# which means that the previous upgrade was interrupted)
|
||||||
|
if [ -s "$NETWORK_CFG" ] && ! [ -s "$NETWORK_SAVED" ]; then
|
||||||
|
mv -f "$NETWORK_CFG" "$NETWORK_SAVED"
|
||||||
|
fi
|
||||||
|
if [ -s "$SYSTEM_CFG" ] && ! [ -s "$SYSTEM_SAVED" ]; then
|
||||||
|
mv -f "$SYSTEM_CFG" "$SYSTEM_SAVED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate a new network config
|
||||||
|
rm -f /etc/board.json "$NETWORK_CFG" "$SYSTEM_CFG"
|
||||||
|
config_generate
|
@ -4,3 +4,6 @@ uci -q batch <<-EOF
|
|||||||
delete gluon.core.reconfigure
|
delete gluon.core.reconfigure
|
||||||
commit
|
commit
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# New config is saved, we can delete the old one
|
||||||
|
rm -f /etc/config/*_gluon-old
|
||||||
|
31
package/gluon-core/luasrc/lib/gluon/upgrade/002-migrate-system
Executable file
31
package/gluon-core/luasrc/lib/gluon/upgrade/002-migrate-system
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local uci = require('simple-uci').cursor()
|
||||||
|
|
||||||
|
-- Migrate system section
|
||||||
|
local system = uci:get_all('system_gluon-old', '@system[0]')
|
||||||
|
if system then
|
||||||
|
uci:tset('system', '@system[0]', system)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Migrate ntp section
|
||||||
|
local ntp = uci:get_all('system_gluon-old', 'ntp')
|
||||||
|
if ntp then
|
||||||
|
uci:tset('system', 'ntp', ntp)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Migrate gpio_switch sections
|
||||||
|
--
|
||||||
|
-- Only the value is copied from the old config, so updates to names and
|
||||||
|
-- pins are preserved
|
||||||
|
uci:foreach('system', 'gpio_switch', function(s)
|
||||||
|
local name = s['.name']
|
||||||
|
local value = uci:get('system_gluon-old', name, 'value')
|
||||||
|
if value then
|
||||||
|
uci:set('system', name, 'value', value)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- No other sections are migrated, so updated LED and RSSI configs can take effect
|
||||||
|
|
||||||
|
uci:save('system')
|
@ -1,15 +1,7 @@
|
|||||||
#!/usr/bin/lua
|
#!/usr/bin/lua
|
||||||
|
|
||||||
local sysconfig = require 'gluon.sysconfig'
|
|
||||||
|
|
||||||
-- Are we already set up?
|
|
||||||
if sysconfig.lan_ifname or sysconfig.wan_ifname then
|
|
||||||
os.exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local platform = require 'gluon.platform'
|
local platform = require 'gluon.platform'
|
||||||
local site = require 'gluon.site'
|
local sysconfig = require 'gluon.sysconfig'
|
||||||
|
|
||||||
local json = require 'jsonc'
|
local json = require 'jsonc'
|
||||||
local uci = require('simple-uci').cursor()
|
local uci = require('simple-uci').cursor()
|
||||||
@ -69,19 +61,15 @@ end
|
|||||||
if wan_ifname and lan_ifname then
|
if wan_ifname and lan_ifname then
|
||||||
sysconfig.wan_ifname = wan_ifname
|
sysconfig.wan_ifname = wan_ifname
|
||||||
sysconfig.lan_ifname = lan_ifname
|
sysconfig.lan_ifname = lan_ifname
|
||||||
|
sysconfig.single_ifname = nil
|
||||||
else
|
else
|
||||||
local single_ifname = lan_ifname or wan_ifname
|
sysconfig.wan_ifname = nil
|
||||||
if site.single_as_lan(false) then
|
sysconfig.lan_ifname = nil
|
||||||
sysconfig.lan_ifname = single_ifname
|
sysconfig.single_ifname = lan_ifname or wan_ifname
|
||||||
else
|
|
||||||
sysconfig.wan_ifname = single_ifname
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
uci:delete('network', 'lan')
|
|
||||||
uci:delete('network', 'wan')
|
|
||||||
|
|
||||||
uci:delete_all('network', 'device')
|
uci:delete_all('network', 'device')
|
||||||
|
uci:delete_all('network', 'interface')
|
||||||
|
|
||||||
uci:save('network')
|
uci:save('network')
|
||||||
|
66
package/gluon-core/luasrc/lib/gluon/upgrade/021-interface-roles
Executable file
66
package/gluon-core/luasrc/lib/gluon/upgrade/021-interface-roles
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local site = require 'gluon.site'
|
||||||
|
local sysconfig = require 'gluon.sysconfig'
|
||||||
|
local uci = require('simple-uci').cursor()
|
||||||
|
local util = require 'gluon.util'
|
||||||
|
|
||||||
|
-- Defaults from site.conf
|
||||||
|
local roles = {
|
||||||
|
lan = site.interfaces.lan.roles({'client'}),
|
||||||
|
wan = site.interfaces.wan.roles({'uplink'}),
|
||||||
|
}
|
||||||
|
roles.single = site.interfaces.single.roles(roles.wan)
|
||||||
|
|
||||||
|
-- Migration of Mesh-on-WAN/LAN setting from Gluon 2021.1 and older (to be removed in 2024)
|
||||||
|
--
|
||||||
|
-- Wired meshing is enabled for single interfaces if either of the settings
|
||||||
|
-- was previously enabled
|
||||||
|
local mesh_lan_disabled = uci:get('network_gluon-old', 'mesh_lan', 'disabled')
|
||||||
|
local mesh_wan_disabled = uci:get('network_gluon-old', 'mesh_wan', 'disabled')
|
||||||
|
if mesh_wan_disabled == '0' then
|
||||||
|
util.add_to_set(roles.wan, 'mesh')
|
||||||
|
util.add_to_set(roles.single, 'mesh')
|
||||||
|
elseif mesh_wan_disabled == '1' then
|
||||||
|
util.remove_from_set(roles.wan, 'mesh')
|
||||||
|
util.remove_from_set(roles.single, 'mesh')
|
||||||
|
end
|
||||||
|
if mesh_lan_disabled == '0' then
|
||||||
|
util.add_to_set(roles.lan, 'mesh')
|
||||||
|
util.add_to_set(roles.single, 'mesh')
|
||||||
|
elseif mesh_lan_disabled == '1' then
|
||||||
|
util.remove_from_set(roles.lan, 'mesh')
|
||||||
|
util.remove_from_set(roles.single, 'mesh')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Migration of single to WAN/LAN or vice-versa (an interface was added or removed)
|
||||||
|
-- We identify the WAN with the single interface in this case
|
||||||
|
--
|
||||||
|
-- These settings only take effect when the section that is the target of the
|
||||||
|
-- migration does not exist yet.
|
||||||
|
if uci:get('gluon', 'iface_wan') then
|
||||||
|
roles.single = uci:get_list('gluon', 'iface_wan', 'role')
|
||||||
|
end
|
||||||
|
if uci:get('gluon', 'iface_single') then
|
||||||
|
roles.wan = uci:get_list('gluon', 'iface_single', 'role')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Non-existing interfaces are nil, so they will not be added to the table
|
||||||
|
local interfaces = {
|
||||||
|
lan = sysconfig.lan_ifname,
|
||||||
|
wan = sysconfig.wan_ifname,
|
||||||
|
single = sysconfig.single_ifname,
|
||||||
|
}
|
||||||
|
|
||||||
|
for iface in pairs(interfaces) do
|
||||||
|
local section_name = 'iface_' .. iface
|
||||||
|
if not uci:get('gluon', section_name) then
|
||||||
|
uci:section('gluon', 'interface', section_name, {
|
||||||
|
-- / prefix refers to sysconfig ifnames
|
||||||
|
name = '/' .. iface,
|
||||||
|
role = roles[iface],
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
uci:save('gluon')
|
@ -1,11 +1,24 @@
|
|||||||
#!/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 wan6 = uci:get_all('network_gluon-old', 'wan6') or {}
|
||||||
|
|
||||||
|
uci:section('network', 'interface', 'loopback', {
|
||||||
|
ifname = 'lo',
|
||||||
|
proto = 'static',
|
||||||
|
ipaddr = '127.0.0.1',
|
||||||
|
netmask = '255.0.0.0',
|
||||||
|
})
|
||||||
|
|
||||||
uci:section('network', 'interface', 'wan', {
|
uci:section('network', 'interface', 'wan', {
|
||||||
ifname = sysconfig.wan_ifname,
|
proto = wan.proto or 'dhcp',
|
||||||
|
ipaddr = wan.ipaddr,
|
||||||
|
netmask = wan.netmask,
|
||||||
|
gateway = wan.gateway,
|
||||||
|
ifname = util.get_role_interfaces(uci, 'uplink'),
|
||||||
type = 'bridge',
|
type = 'bridge',
|
||||||
igmp_snooping = true,
|
igmp_snooping = true,
|
||||||
multicast_querier = false,
|
multicast_querier = false,
|
||||||
@ -13,12 +26,10 @@ uci:section('network', 'interface', 'wan', {
|
|||||||
auto = true,
|
auto = true,
|
||||||
})
|
})
|
||||||
|
|
||||||
if not uci:get('network', 'wan', 'proto') then
|
|
||||||
uci:set('network', 'wan', 'proto', 'dhcp')
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
uci:section('network', 'interface', 'wan6', {
|
uci:section('network', 'interface', 'wan6', {
|
||||||
|
proto = wan6.proto or 'dhcpv6',
|
||||||
|
ip6addr = wan6.ip6addr,
|
||||||
|
ip6gw = wan6.ip6gw,
|
||||||
ifname = 'br-wan',
|
ifname = 'br-wan',
|
||||||
peerdns = false,
|
peerdns = false,
|
||||||
ip6table = 1,
|
ip6table = 1,
|
||||||
@ -26,11 +37,6 @@ uci:section('network', 'interface', 'wan6', {
|
|||||||
reqprefix = 'no',
|
reqprefix = 'no',
|
||||||
})
|
})
|
||||||
|
|
||||||
if not uci:get('network', 'wan6', 'proto') then
|
|
||||||
uci:set('network', 'wan6', 'proto', 'dhcpv6')
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
uci:section('network', 'rule6', 'wan6_lookup', {
|
uci:section('network', 'rule6', 'wan6_lookup', {
|
||||||
mark = '0x01/0x01',
|
mark = '0x01/0x01',
|
||||||
lookup = 1,
|
lookup = 1,
|
||||||
|
@ -106,8 +106,6 @@ end
|
|||||||
local function delete_ibss(radio_name)
|
local function delete_ibss(radio_name)
|
||||||
local name = 'ibss_' .. radio_name
|
local name = 'ibss_' .. radio_name
|
||||||
|
|
||||||
uci:delete('network', name)
|
|
||||||
uci:delete('network', name .. '_vlan')
|
|
||||||
uci:delete('wireless', name)
|
uci:delete('wireless', name)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -118,8 +116,6 @@ local function configure_mesh(config, radio, index, suffix, disabled)
|
|||||||
local macfilter = uci:get('wireless', name, 'macfilter')
|
local macfilter = uci:get('wireless', name, 'macfilter')
|
||||||
local maclist = uci:get('wireless', name, 'maclist')
|
local maclist = uci:get('wireless', name, 'maclist')
|
||||||
|
|
||||||
uci:delete('network', name)
|
|
||||||
uci:delete('network', name .. '_vlan')
|
|
||||||
uci:delete('wireless', name)
|
uci:delete('wireless', name)
|
||||||
|
|
||||||
if not config then
|
if not config then
|
||||||
|
48
package/gluon-core/luasrc/lib/gluon/upgrade/210-interface-mesh
Executable file
48
package/gluon-core/luasrc/lib/gluon/upgrade/210-interface-mesh
Executable 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')
|
@ -1,25 +0,0 @@
|
|||||||
#!/usr/bin/lua
|
|
||||||
|
|
||||||
local site = require 'gluon.site'
|
|
||||||
local uci = require('simple-uci').cursor()
|
|
||||||
|
|
||||||
uci:section('network', 'interface', 'mesh_wan', {
|
|
||||||
ifname = 'br-wan',
|
|
||||||
proto = 'gluon_wired',
|
|
||||||
index = 0,
|
|
||||||
vxlan = site.mesh.vxlan(true),
|
|
||||||
})
|
|
||||||
|
|
||||||
local enable = site.mesh_on_wan(false)
|
|
||||||
local old_auto = uci:get('network', 'mesh_wan', 'auto')
|
|
||||||
local old_disabled = uci:get('network', 'mesh_wan', 'disabled')
|
|
||||||
if old_auto ~= nil or old_disabled ~= nil then
|
|
||||||
enable = old_auto ~= '0' and old_disabled ~= '1'
|
|
||||||
end
|
|
||||||
uci:set('network', 'mesh_wan', 'disabled', not enable)
|
|
||||||
|
|
||||||
if uci:get('network', 'mesh_wan', 'transitive') == nil then
|
|
||||||
uci:set('network', 'mesh_wan', 'transitive', true)
|
|
||||||
end
|
|
||||||
|
|
||||||
uci:save('network')
|
|
@ -1,53 +0,0 @@
|
|||||||
#!/usr/bin/lua
|
|
||||||
|
|
||||||
local site = require 'gluon.site'
|
|
||||||
local util = require 'gluon.util'
|
|
||||||
local sysconfig = require 'gluon.sysconfig'
|
|
||||||
|
|
||||||
local uci = require('simple-uci').cursor()
|
|
||||||
|
|
||||||
if not sysconfig.lan_ifname then
|
|
||||||
os.exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
uci:section('network', 'interface', 'mesh_lan', {
|
|
||||||
ifname = sysconfig.lan_ifname,
|
|
||||||
igmp_snooping = false,
|
|
||||||
proto = 'gluon_wired',
|
|
||||||
index = 4,
|
|
||||||
vxlan = site.mesh.vxlan(true),
|
|
||||||
})
|
|
||||||
|
|
||||||
if sysconfig.lan_ifname:match(' ') then
|
|
||||||
uci:set('network', 'mesh_lan', 'type', 'bridge')
|
|
||||||
else
|
|
||||||
uci:delete('network', 'mesh_lan', 'type')
|
|
||||||
end
|
|
||||||
|
|
||||||
local enable = site.mesh_on_lan(false)
|
|
||||||
local old_auto = uci:get('network', 'mesh_lan', 'auto')
|
|
||||||
local old_disabled = uci:get('network', 'mesh_lan', 'disabled')
|
|
||||||
if old_auto ~= nil or old_disabled ~= nil then
|
|
||||||
enable = old_auto ~= '0' and old_disabled ~= '1'
|
|
||||||
end
|
|
||||||
|
|
||||||
if enable then
|
|
||||||
local interfaces = uci:get_list('network', 'client', 'ifname')
|
|
||||||
|
|
||||||
if interfaces then
|
|
||||||
for lanif in sysconfig.lan_ifname:gmatch('%S+') do
|
|
||||||
if util.contains(interfaces, lanif) then
|
|
||||||
enable = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
uci:set('network', 'mesh_lan', 'disabled', not enable)
|
|
||||||
|
|
||||||
if uci:get('network', 'mesh_lan', 'transitive') == nil then
|
|
||||||
uci:set('network', 'mesh_lan', 'transitive', true)
|
|
||||||
end
|
|
||||||
|
|
||||||
uci:save('network')
|
|
@ -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
|
||||||
|
19
package/gluon-core/luasrc/lib/gluon/upgrade/997-migrate-preserved
Executable file
19
package/gluon-core/luasrc/lib/gluon/upgrade/997-migrate-preserved
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local uci = require('simple-uci').cursor()
|
||||||
|
|
||||||
|
for _, config in ipairs({'system', 'network'}) do
|
||||||
|
uci:foreach(config .. '_gluon-old', nil, function(s)
|
||||||
|
if s.gluon_preserve ~= '1' then return end
|
||||||
|
|
||||||
|
-- Unnamed sections can't be preserved
|
||||||
|
if s['.anonymous'] then return end
|
||||||
|
|
||||||
|
-- We don't allow overwriting existing sections
|
||||||
|
if uci:get(config, s['.name']) then return end
|
||||||
|
|
||||||
|
uci:section(config, s['.type'], s['.name'], s)
|
||||||
|
end)
|
||||||
|
|
||||||
|
uci:save(config)
|
||||||
|
end
|
@ -11,6 +11,10 @@ local function get(_, name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function set(_, name, val)
|
local function set(_, name, val)
|
||||||
|
if val == get(nil, name) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if val then
|
if val then
|
||||||
local f = io.open(sysconfigdir .. name, 'w+')
|
local f = io.open(sysconfigdir .. name, 'w+')
|
||||||
f:write(val, '\n')
|
f:write(val, '\n')
|
||||||
|
@ -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)
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
local uci = require('simple-uci').cursor()
|
local uci = require('simple-uci').cursor()
|
||||||
|
|
||||||
uci:delete('network', 'mmfd')
|
|
||||||
uci:section('network', 'interface', 'mmfd', {
|
uci:section('network', 'interface', 'mmfd', {
|
||||||
proto = 'static',
|
proto = 'static',
|
||||||
ifname = 'mmfd0',
|
ifname = 'mmfd0',
|
||||||
|
@ -9,14 +9,12 @@ local uci = require('simple-uci').cursor()
|
|||||||
uci:delete('batman-adv', 'bat0')
|
uci:delete('batman-adv', 'bat0')
|
||||||
uci:save('batman-adv')
|
uci:save('batman-adv')
|
||||||
|
|
||||||
local gw_mode = uci:get('network', 'gluon_bat0', 'gw_mode') or 'client'
|
local gw_mode = uci:get('network_gluon-old', 'gluon_bat0', 'gw_mode') or 'client'
|
||||||
uci:delete('network', 'gluon_bat0')
|
|
||||||
uci:section('network', 'interface', 'gluon_bat0', {
|
uci:section('network', 'interface', 'gluon_bat0', {
|
||||||
proto = 'gluon_bat0',
|
proto = 'gluon_bat0',
|
||||||
gw_mode = gw_mode,
|
gw_mode = gw_mode,
|
||||||
})
|
})
|
||||||
|
|
||||||
uci:delete('network', 'bat0')
|
|
||||||
uci:section('network', 'interface', 'bat0', {
|
uci:section('network', 'interface', 'bat0', {
|
||||||
ifname = 'bat0',
|
ifname = 'bat0',
|
||||||
proto = 'none',
|
proto = 'none',
|
||||||
|
@ -21,7 +21,6 @@ uci:section('network', 'interface', 'client', {
|
|||||||
query_response_interval = 500,
|
query_response_interval = 500,
|
||||||
})
|
})
|
||||||
|
|
||||||
uci:delete('network', 'local_node_route6')
|
|
||||||
uci:section('network', 'route6', 'local_node_route6', {
|
uci:section('network', 'route6', 'local_node_route6', {
|
||||||
interface = 'client',
|
interface = 'client',
|
||||||
target = site.prefix6(),
|
target = site.prefix6(),
|
||||||
|
@ -8,8 +8,8 @@ local uci = require('simple-uci').cursor()
|
|||||||
-- fix up potentially duplicate MAC addresses (for meshing)
|
-- fix up potentially duplicate MAC addresses (for meshing)
|
||||||
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))
|
||||||
else
|
|
||||||
uci:delete('network', 'wan', 'macaddr')
|
|
||||||
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')
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
local uci = require('simple-uci').cursor()
|
local uci = require('simple-uci').cursor()
|
||||||
local site = require 'gluon.site'
|
local site = require 'gluon.site'
|
||||||
|
|
||||||
local private_key = uci:get("network", 'wg_mesh', "private_key")
|
local private_key = uci:get("network_gluon-old", 'wg_mesh', "private_key")
|
||||||
|
|
||||||
if not private_key or not private_key:match("^" .. ("[%a%d+/]"):rep(42) .. "[AEIMQUYcgkosw480]=$") then
|
if not private_key or not private_key:match("^" .. ("[%a%d+/]"):rep(42) .. "[AEIMQUYcgkosw480]=$") then
|
||||||
private_key = "generate"
|
private_key = "generate"
|
||||||
|
@ -3,13 +3,8 @@
|
|||||||
local platform = require 'gluon.platform'
|
local platform = require 'gluon.platform'
|
||||||
local sysconfig = require 'gluon.sysconfig'
|
local sysconfig = require 'gluon.sysconfig'
|
||||||
|
|
||||||
|
|
||||||
if sysconfig.setup_ifname then
|
|
||||||
os.exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
if platform.is_outdoor_device() then
|
if platform.is_outdoor_device() then
|
||||||
sysconfig.setup_ifname = sysconfig.wan_ifname or sysconfig.lan_ifname
|
sysconfig.setup_ifname = sysconfig.single_ifname or sysconfig.wan_ifname
|
||||||
else
|
else
|
||||||
sysconfig.setup_ifname = sysconfig.lan_ifname or sysconfig.wan_ifname
|
sysconfig.setup_ifname = sysconfig.single_ifname or sysconfig.lan_ifname
|
||||||
end
|
end
|
||||||
|
@ -28,6 +28,9 @@ msgstr "PoE-Passthrough aktivieren"
|
|||||||
msgid "Enable PoE Power Port %s"
|
msgid "Enable PoE Power Port %s"
|
||||||
msgstr "PoE-Ausgabe auf Port %s aktivieren"
|
msgstr "PoE-Ausgabe auf Port %s aktivieren"
|
||||||
|
|
||||||
|
msgid "Enable meshing on the Ethernet interface"
|
||||||
|
msgstr "Mesh auf dem Ethernet-Port aktivieren"
|
||||||
|
|
||||||
msgid "Enable meshing on the LAN interface"
|
msgid "Enable meshing on the LAN interface"
|
||||||
msgstr "Mesh auf dem LAN-Port aktivieren"
|
msgstr "Mesh auf dem LAN-Port aktivieren"
|
||||||
|
|
||||||
|
@ -28,6 +28,9 @@ msgstr ""
|
|||||||
msgid "Enable PoE Power Port %s"
|
msgid "Enable PoE Power Port %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enable meshing on the Ethernet interface"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Enable meshing on the LAN interface"
|
msgid "Enable meshing on the LAN interface"
|
||||||
msgstr "Activer le réseau MESH sur le port LAN"
|
msgstr "Activer le réseau MESH sur le port LAN"
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@ msgstr ""
|
|||||||
msgid "Enable PoE Power Port %s"
|
msgid "Enable PoE Power Port %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enable meshing on the Ethernet interface"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Enable meshing on the LAN interface"
|
msgid "Enable meshing on the LAN interface"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -76,36 +76,37 @@ end
|
|||||||
|
|
||||||
s = f:section(Section)
|
s = f:section(Section)
|
||||||
|
|
||||||
local mesh_wan = s:option(Flag, "mesh_wan", translate("Enable meshing on the WAN interface"))
|
local wired_mesh_help = {
|
||||||
mesh_wan.default = not uci:get_bool("network", "mesh_wan", "disabled")
|
single = translate('Enable meshing on the Ethernet interface'),
|
||||||
|
wan = translate('Enable meshing on the WAN interface'),
|
||||||
|
lan = translate('Enable meshing on the LAN interface'),
|
||||||
|
}
|
||||||
|
|
||||||
function mesh_wan:write(data)
|
local function wired_mesh(iface)
|
||||||
uci:set("network", "mesh_wan", "disabled", not data)
|
if not sysconfig[iface .. '_ifname'] then return end
|
||||||
end
|
local iface_roles = uci:get_list('gluon', 'iface_' .. iface, 'role')
|
||||||
|
|
||||||
if sysconfig.lan_ifname then
|
local option = s:option(Flag, 'mesh_' .. iface, wired_mesh_help[iface])
|
||||||
s = f:section(Section)
|
option.default = util.contains(iface_roles, 'mesh') ~= false
|
||||||
|
|
||||||
local mesh_lan = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface"))
|
function option:write(data)
|
||||||
mesh_lan.default = not uci:get_bool("network", "mesh_lan", "disabled")
|
local roles = uci:get_list('gluon', 'iface_' .. iface, 'role')
|
||||||
|
if data then
|
||||||
function mesh_lan:write(data)
|
util.add_to_set(roles, 'mesh')
|
||||||
uci:set("network", "mesh_lan", "disabled", not data)
|
else
|
||||||
|
util.remove_from_set(roles, 'mesh')
|
||||||
local interfaces = uci:get_list("network", "client", "ifname")
|
|
||||||
|
|
||||||
for lanif in sysconfig.lan_ifname:gmatch('%S+') do
|
|
||||||
if data then
|
|
||||||
util.remove_from_set(interfaces, lanif)
|
|
||||||
else
|
|
||||||
util.add_to_set(interfaces, lanif)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
uci:set_list('gluon', 'iface_' .. iface, 'role', roles)
|
||||||
|
|
||||||
uci:set_list("network", "client", "ifname", interfaces)
|
-- Reconfigure on next reboot
|
||||||
|
uci:set('gluon', 'core', 'reconfigure', true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
wired_mesh('single')
|
||||||
|
wired_mesh('wan')
|
||||||
|
wired_mesh('lan')
|
||||||
|
|
||||||
local section
|
local section
|
||||||
uci:foreach("system", "gpio_switch", function(si)
|
uci:foreach("system", "gpio_switch", function(si)
|
||||||
if si[".name"]:match("poe") then
|
if si[".name"]:match("poe") then
|
||||||
@ -160,7 +161,7 @@ function f:write()
|
|||||||
uci:delete("network", "wan6", "ip6gw")
|
uci:delete("network", "wan6", "ip6gw")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
uci:commit('gluon')
|
||||||
uci:commit("network")
|
uci:commit("network")
|
||||||
uci:commit('system')
|
uci:commit('system')
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user