diff options
| author | Christian Breunig <christian@breunig.cc> | 2025-09-13 13:16:40 +0200 |
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2025-09-13 13:16:40 +0200 |
| commit | f08a5700e725a2ed4c53320b310167826953215d (patch) | |
| tree | 9dd1483553bcdc380a956f2596185da463ff95b5 /src/migration-scripts/interfaces | |
| parent | 6a47b699577904eb3e5866c27ab2813058cc9ed9 (diff) | |
| download | vyos-1x-f08a5700e725a2ed4c53320b310167826953215d.tar.gz vyos-1x-f08a5700e725a2ed4c53320b310167826953215d.zip | |
dhcpv6: T7646: restore missing default route after upgrade
Commit de44c6aef249 ("interface: T7379: do not request SLAAC default route when
only DHCPv6 is set") introduced a behavioral change while addressing an earlier
issue fixed in e9fb2078d5ea ("interface: T7375: SLAAC assigned address is not
cleared when removing SLAAC").
This change caused unintended connectivity loss after upgrading to VyOS 1.4.3.
The underlying reason is that VyOS now requires explicit configuration to
determine how IPv6 addressing and routing should be handled, rather than making
assumptions: Requesting a DHCPv6 address alone will correctly assign an address.
However, since the IPv6 default route is typically advertised via SLAAC (and not
DHCPv6), SLAAC must also be explicitly enabled to receive the default route.
Historically, this distinction was implicit and did not require additional
configuration.
To preserve backward compatibility, a configuration migrator has been added.
It inspects existing configurations that only request a DHCPv6 address and
automatically appends the required CLI node to also enable SLAAC, ensuring that
the default route is restored after upgrade.
Diffstat (limited to 'src/migration-scripts/interfaces')
| -rw-r--r-- | src/migration-scripts/interfaces/32-to-33 | 51 | ||||
| -rw-r--r-- | src/migration-scripts/interfaces/33-to-34 | 40 |
2 files changed, 72 insertions, 19 deletions
diff --git a/src/migration-scripts/interfaces/32-to-33 b/src/migration-scripts/interfaces/32-to-33 index ccda04d0c..af7b7f497 100644 --- a/src/migration-scripts/interfaces/32-to-33 +++ b/src/migration-scripts/interfaces/32-to-33 @@ -13,28 +13,41 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# T6318: WiFi country-code should be set system-wide instead of per-device -from vyos.configtree import ConfigTree +# T7646: restore behavior of IPv6 default route if only dhcpv6 was defined but +# not "ipv6 address autoconf" -base = ['interfaces', 'wireless'] +from vyos.configtree import ConfigTree def migrate(config: ConfigTree) -> None: - if not config.exists(base): - # Nothing to do - return + for type in config.list_nodes(['interfaces']): + for interface in config.list_nodes(['interfaces', type]): + iface_base_path = ['interfaces', type, interface] + dhcpv6_addr_path = iface_base_path + ['address', 'dhcpv6'] + autoconf_path = iface_base_path + ['ipv6', 'address', 'autoconf'] + if config.exists(dhcpv6_addr_path) and not config.exists(autoconf_path): + config.set(autoconf_path) + + vif_path = iface_base_path + ['vif'] + if config.exists(vif_path): + for vif in config.list_nodes(vif_path): + vif_dhcpv6_addr_path = vif_path + [vif, 'address'] + vif_autoconf_path = vif_path + [vif, 'ipv6', 'address', 'autoconf'] + if config.exists(vif_dhcpv6_addr_path) and not config.exists(vif_autoconf_path): + config.set(vif_autoconf_path) - installed = False - for interface in config.list_nodes(base): - cc_path = base + [interface, 'country-code'] - if config.exists(cc_path): - tmp = config.return_value(cc_path) - config.delete(cc_path) + vif_s_path = iface_base_path + ['vif-s'] + if config.exists(vif_s_path): + for vif_s in config.list_nodes(vif_s_path): + vif_s_dhcpv6_addr_path = vif_s_path + [vif_s, 'address'] + vif_s_autoconf_path = vif_s_path + [vif_s, 'ipv6', 'address', 'autoconf'] + if config.exists(vif_s_dhcpv6_addr_path) and not config.exists(vif_s_autoconf_path): + config.set(vif_s_autoconf_path) - # There can be only ONE wireless country-code per device, everything - # else makes no sense as a WIFI router can not operate in two - # different countries - if not installed: - config.set(['system', 'wireless', 'country-code'], value=tmp) - installed = True + vif_c_path = iface_base_path + ['vif-s', vif_s, 'vif-c'] + if config.exists(vif_c_path): + for vif_c in config.list_nodes(vif_c_path): + vif_c_dhcpv6_addr_path = vif_c_path + [vif_c, 'address'] + vif_c_autoconf_path = vif_c_path + [vif_c, 'ipv6', 'address', 'autoconf'] + if config.exists(vif_c_dhcpv6_addr_path) and not config.exists(vif_c_autoconf_path): + config.set(vif_c_autoconf_path) diff --git a/src/migration-scripts/interfaces/33-to-34 b/src/migration-scripts/interfaces/33-to-34 new file mode 100644 index 000000000..ccda04d0c --- /dev/null +++ b/src/migration-scripts/interfaces/33-to-34 @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# +# Copyright VyOS maintainers and contributors <maintainers@vyos.io> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# T6318: WiFi country-code should be set system-wide instead of per-device + +from vyos.configtree import ConfigTree + +base = ['interfaces', 'wireless'] + +def migrate(config: ConfigTree) -> None: + if not config.exists(base): + # Nothing to do + return + + installed = False + for interface in config.list_nodes(base): + cc_path = base + [interface, 'country-code'] + if config.exists(cc_path): + tmp = config.return_value(cc_path) + config.delete(cc_path) + + # There can be only ONE wireless country-code per device, everything + # else makes no sense as a WIFI router can not operate in two + # different countries + if not installed: + config.set(['system', 'wireless', 'country-code'], value=tmp) + installed = True |
