Skip to content

Commit f08a570

Browse files
committed
dhcpv6: T7646: restore missing default route after upgrade
Commit de44c6a ("interface: T7379: do not request SLAAC default route when only DHCPv6 is set") introduced a behavioral change while addressing an earlier issue fixed in e9fb207 ("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.
1 parent 6a47b69 commit f08a570

5 files changed

Lines changed: 255 additions & 20 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<!-- include start from include/version/interfaces-version.xml.i -->
2-
<syntaxVersion component='interfaces' version='33'></syntaxVersion>
2+
<syntaxVersion component='interfaces' version='34'></syntaxVersion>
33
<!-- include end -->

smoketest/config-tests/basic-ipv6

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
set interfaces ethernet eth0 vif 5 address 'dhcpv6'
2+
set interfaces ethernet eth0 vif 5 ipv6 address autoconf
3+
set interfaces ethernet eth0 vif-s 10 address 'dhcpv6'
4+
set interfaces ethernet eth0 vif-s 10 ipv6 address autoconf
5+
set interfaces ethernet eth0 vif-s 10 vif-c 20 address 'dhcpv6'
6+
set interfaces ethernet eth0 vif-s 10 vif-c 20 ipv6 address autoconf
7+
set interfaces ethernet eth1 duplex 'auto'
8+
set interfaces ethernet eth1 speed 'auto'
9+
set interfaces ethernet eth1 vif 50
10+
set interfaces ethernet eth1 vif-s 60 vif-c 70
11+
set interfaces ethernet eth2 duplex 'auto'
12+
set interfaces ethernet eth2 speed 'auto'
13+
set interfaces loopback lo
14+
set interfaces pppoe pppoe0 authentication password 'vyos'
15+
set interfaces pppoe pppoe0 authentication username 'vyos'
16+
set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth1.50 address '1'
17+
set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth1.50 sla-id '0'
18+
set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth1.60 address '1'
19+
set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth1.60 sla-id '1'
20+
set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth1.60.70 address '1'
21+
set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface eth1.60.70 sla-id '1'
22+
set interfaces pppoe pppoe0 dhcpv6-options pd 0 length '56'
23+
set interfaces pppoe pppoe0 no-peer-dns
24+
set interfaces pppoe pppoe0 source-interface 'eth2'
25+
set service ntp allow-client address '2001:db8::/32'
26+
set service ntp server time1.vyos.net
27+
set service ntp server time2.vyos.net
28+
set service router-advert interface eth1.50 prefix ::/64 preferred-lifetime '2700'
29+
set service router-advert interface eth1.50 prefix ::/64 valid-lifetime '5400'
30+
set service router-advert interface eth1.60 prefix ::/64
31+
set service router-advert interface eth1.60.70 prefix ::/64
32+
set system config-management commit-revisions '15'
33+
set system domain-name 'vyos.net'
34+
set system host-name 'ipv6-r1'
35+
set system login user vyos authentication encrypted-password '$6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/'
36+
set system login user vyos authentication plaintext-password ''
37+
set system name-server '2001:db8::1'
38+
set system name-server '2001:db8::2'
39+
set system syslog local facility all level 'debug'
40+
set system console device ttyS0 speed '115200'

smoketest/configs/basic-ipv6

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
interfaces {
2+
ethernet eth0 {
3+
duplex auto
4+
offload {
5+
gro
6+
gso
7+
sg
8+
tso
9+
}
10+
speed auto
11+
vif 5 {
12+
address dhcpv6
13+
}
14+
vif-s 10 {
15+
address dhcpv6
16+
vif-c 20 {
17+
address dhcpv6
18+
}
19+
}
20+
}
21+
ethernet eth1 {
22+
duplex auto
23+
speed auto
24+
vif 50 {
25+
}
26+
vif-s 60 {
27+
vif-c 70 {
28+
}
29+
}
30+
}
31+
ethernet eth2 {
32+
duplex auto
33+
speed auto
34+
}
35+
loopback lo {
36+
}
37+
pppoe pppoe0 {
38+
authentication {
39+
password vyos
40+
user vyos
41+
}
42+
default-route force
43+
dhcpv6-options {
44+
pd 0 {
45+
interface eth1.50 {
46+
address 1
47+
sla-id 0
48+
}
49+
interface eth1.60 {
50+
address 1
51+
sla-id 1
52+
}
53+
interface eth1.60.70 {
54+
address 1
55+
sla-id 1
56+
}
57+
length 56
58+
}
59+
}
60+
ipv6 {
61+
address {
62+
autoconf
63+
}
64+
}
65+
no-peer-dns
66+
source-interface eth2
67+
}
68+
}
69+
service {
70+
router-advert {
71+
interface eth1.50 {
72+
prefix ::/64 {
73+
preferred-lifetime 2700
74+
valid-lifetime 5400
75+
}
76+
}
77+
interface eth1.60 {
78+
prefix ::/64 {
79+
}
80+
}
81+
interface eth1.60.70 {
82+
prefix ::/64 {
83+
}
84+
}
85+
}
86+
}
87+
system {
88+
config-management {
89+
commit-revisions 15
90+
}
91+
conntrack {
92+
modules {
93+
ftp
94+
h323
95+
nfs
96+
pptp
97+
sqlnet
98+
tftp
99+
}
100+
}
101+
console {
102+
device ttyS0 {
103+
speed 115200
104+
}
105+
}
106+
domain-name vyos.net
107+
host-name ipv6-r1
108+
login {
109+
user vyos {
110+
authentication {
111+
encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
112+
plaintext-password ""
113+
}
114+
}
115+
}
116+
name-server 2001:db8::1
117+
name-server 2001:db8::2
118+
ntp {
119+
allow-clients {
120+
address 2001:db8::/32
121+
}
122+
server time1.vyos.net {
123+
}
124+
server time2.vyos.net {
125+
}
126+
}
127+
syslog {
128+
global {
129+
facility all {
130+
level debug
131+
}
132+
facility protocols {
133+
level debug
134+
}
135+
}
136+
}
137+
time-zone Europe/Berlin
138+
}
139+
140+
// Warning: Do not remove the following line.
141+
// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:container@1:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@22:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1"
142+
// Release version: 1.3.4

src/migration-scripts/interfaces/32-to-33

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,41 @@
1313
#
1414
# You should have received a copy of the GNU General Public License
1515
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
#
17-
# T6318: WiFi country-code should be set system-wide instead of per-device
1816

19-
from vyos.configtree import ConfigTree
17+
# T7646: restore behavior of IPv6 default route if only dhcpv6 was defined but
18+
# not "ipv6 address autoconf"
2019

21-
base = ['interfaces', 'wireless']
20+
from vyos.configtree import ConfigTree
2221

2322
def migrate(config: ConfigTree) -> None:
24-
if not config.exists(base):
25-
# Nothing to do
26-
return
23+
for type in config.list_nodes(['interfaces']):
24+
for interface in config.list_nodes(['interfaces', type]):
25+
iface_base_path = ['interfaces', type, interface]
26+
dhcpv6_addr_path = iface_base_path + ['address', 'dhcpv6']
27+
autoconf_path = iface_base_path + ['ipv6', 'address', 'autoconf']
28+
if config.exists(dhcpv6_addr_path) and not config.exists(autoconf_path):
29+
config.set(autoconf_path)
30+
31+
vif_path = iface_base_path + ['vif']
32+
if config.exists(vif_path):
33+
for vif in config.list_nodes(vif_path):
34+
vif_dhcpv6_addr_path = vif_path + [vif, 'address']
35+
vif_autoconf_path = vif_path + [vif, 'ipv6', 'address', 'autoconf']
36+
if config.exists(vif_dhcpv6_addr_path) and not config.exists(vif_autoconf_path):
37+
config.set(vif_autoconf_path)
2738

28-
installed = False
29-
for interface in config.list_nodes(base):
30-
cc_path = base + [interface, 'country-code']
31-
if config.exists(cc_path):
32-
tmp = config.return_value(cc_path)
33-
config.delete(cc_path)
39+
vif_s_path = iface_base_path + ['vif-s']
40+
if config.exists(vif_s_path):
41+
for vif_s in config.list_nodes(vif_s_path):
42+
vif_s_dhcpv6_addr_path = vif_s_path + [vif_s, 'address']
43+
vif_s_autoconf_path = vif_s_path + [vif_s, 'ipv6', 'address', 'autoconf']
44+
if config.exists(vif_s_dhcpv6_addr_path) and not config.exists(vif_s_autoconf_path):
45+
config.set(vif_s_autoconf_path)
3446

35-
# There can be only ONE wireless country-code per device, everything
36-
# else makes no sense as a WIFI router can not operate in two
37-
# different countries
38-
if not installed:
39-
config.set(['system', 'wireless', 'country-code'], value=tmp)
40-
installed = True
47+
vif_c_path = iface_base_path + ['vif-s', vif_s, 'vif-c']
48+
if config.exists(vif_c_path):
49+
for vif_c in config.list_nodes(vif_c_path):
50+
vif_c_dhcpv6_addr_path = vif_c_path + [vif_c, 'address']
51+
vif_c_autoconf_path = vif_c_path + [vif_c, 'ipv6', 'address', 'autoconf']
52+
if config.exists(vif_c_dhcpv6_addr_path) and not config.exists(vif_c_autoconf_path):
53+
config.set(vif_c_autoconf_path)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License version 2 or later as
7+
# published by the Free Software Foundation.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
#
17+
# T6318: WiFi country-code should be set system-wide instead of per-device
18+
19+
from vyos.configtree import ConfigTree
20+
21+
base = ['interfaces', 'wireless']
22+
23+
def migrate(config: ConfigTree) -> None:
24+
if not config.exists(base):
25+
# Nothing to do
26+
return
27+
28+
installed = False
29+
for interface in config.list_nodes(base):
30+
cc_path = base + [interface, 'country-code']
31+
if config.exists(cc_path):
32+
tmp = config.return_value(cc_path)
33+
config.delete(cc_path)
34+
35+
# There can be only ONE wireless country-code per device, everything
36+
# else makes no sense as a WIFI router can not operate in two
37+
# different countries
38+
if not installed:
39+
config.set(['system', 'wireless', 'country-code'], value=tmp)
40+
installed = True

0 commit comments

Comments
 (0)