SUMMARY
The way VyOS interprets the Cloud-Init network-config, some configurations may lead to the boot configuration being broken and uncommittable.
STEPS TO REPRODUCE
Boot the router with a Cloud-Init configuration containing the following network-config (and yes, the second static stanza should rather be static6, that's a bug in my hypervisor but it doesn't matter much):
version: 1
config:
- type: physical
name: eth0
mac_address: '00:12:34:56:78:9a'
subnets:
- type: static
address: '10.0.2.21'
netmask: '255.255.255.0'
gateway: '10.0.2.2'
- type: static
address: 'fec0:de:ad:f00d::1/64'
gateway: 'fec0:de:ad:f00d::fffe'
- type: nameserver
address:
- '8.8.8.8'
search:
- 'example.com'OBSERVED RESULT
Confiiguration commit fails. User is unable to login.
EXPECTED RESULT
Network configuration is applied. User can login.
SOFTWARE/OS VERSIONS
vyos-cloud-init @ 393cc322629604843b98da970b0761965a7a268e
ADDITIONAL INFORMATION
This is an issue in set_config_interfaces_v1(). The following code is wrong:
if subnet['type'] in ['static', 'static6']:
# ... snip ...
# configure gateway
if 'gateway' in subnet and subnet['gateway'] != '0.0.0.0':
logger.debug("Configuring gateway for {}: {}".format(iface_name, subnet['gateway']))
config.set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'], value=subnet['gateway'], replace=True)
config.set_tag(['protocols', 'static', 'route'])
config.set_tag(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'])With the above configuration, this will try to add a route for 0.0.0.0/0 even for the IPv6 gateway, resulting in a later failure to mount the configuration correctly. A simple fix would be to write it like this:
# configure gateway
if ip_version == 4 and 'gateway' in subnet and subnet['gateway'] != '0.0.0.0':
logger.debug("Configuring gateway for {}: {}".format(iface_name, subnet['gateway']))
config.delete(['protocols', 'static', 'route', '0.0.0.0/0'])
config.set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'], value=subnet['gateway'], replace=True)
config.set_tag(['protocols', 'static', 'route'])
config.set_tag(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'])
if ip_version == 6 and 'gateway' in subnet and subnet['gateway'] != '::':
logger.debug("Configuring gateway for {}: {}".format(iface_name, subnet['gateway']))
config.delete(['protocols', 'static', 'route6', '::/0'])
config.set(['protocols', 'static', 'route6', '::/0', 'next-hop'], value=subnet['gateway'], replace=True)
config.set_tag(['protocols', 'static', 'route6'])
config.set_tag(['protocols', 'static', 'route6', '::/0', 'next-hop'])