Skip to content

vyos: Fix handling of IPv6 netmasks on OpenStack#90

Open
jplitza wants to merge 3 commits intovyos:currentfrom
jplitza:patch-1
Open

vyos: Fix handling of IPv6 netmasks on OpenStack#90
jplitza wants to merge 3 commits intovyos:currentfrom
jplitza:patch-1

Conversation

@jplitza
Copy link
Copy Markdown

@jplitza jplitza commented Mar 25, 2026

Proposed Commit Message

On OpenStack with a network with DHCP disabled, IPv6 routes are passed like this:

    'routes': [{'network': '::', 'netmask': '::', 'gateway': '2001:db8::1'}]

This results in a call to ipaddress.ip_network('::/::'), which Python does not regard as valid network notation.

So this commit uses cloudinit.net.network_state.ipv6_mask_to_net_prefix() to calculate the prefix length from that notation.

Additional Context

Test Steps

Checklist:

  • My code follows the process laid out in the documentation
  • I have updated or added any unit tests accordingly
  • I have updated or added any documentation accordingly

On OpenStack with a network with DHCP disabled, IPv6 routes are passed like this:

    'routes': [{'network': '::', 'netmask': '::', 'gateway': '2001:db8::1'}]

This results in a call to ipaddress.ip_network('::/::'), which Python does not regard as valid network notation.

So this commit manually  calculates the prefix length from that notation.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes VyOS network configuration on OpenStack when DHCP is disabled and IPv6 route netmasks are provided in address-form (e.g. ::) instead of a prefix length, which can cause invalid ipaddress.ip_network parsing.

Changes:

  • Added an IPv6 netmask-to-prefix-length conversion helper.
  • Updated v1 subnet route configuration to convert IPv6 netmasks before calling ipaddress.ip_network.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +458 to +462
netmask = ipaddress.ip_address(item['netmask'])
if netmask.version == 6:
netmask = ipaddress_to_prefixlen(netmask)
ip_network = ipaddress.ip_network('{}/{}'.format(
item['network'], item['netmask']))
item['network'], netmask))
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In route handling, netmask = ipaddress.ip_address(item['netmask']) will break when item['netmask'] is an integer prefix length (e.g. 64) or a prefix string (e.g. '64'): ip_address(64) becomes an IPv4 address and '64' raises ValueError, leading to invalid ip_network('{}/{}'.format(item['network'], netmask)). Consider passing through prefix lengths unchanged and only converting when the netmask is an IPv6 address-form string (like '::'/'ffff:...'), or use the existing cloudinit.net.network_state.ipv6_mask_to_net_prefix helper which already supports both prefix and IPv6-netmask inputs.

Copilot uses AI. Check for mistakes.
Comment on lines +133 to +146
# Python's ipaddress.ip_network does not support something like ::/:: as
# input. So we have to convert the IPv6 address notation of the netmask
# to the integer prefix length.
def ipaddress_to_prefixlen(addr):
prefixlen = addr.max_prefixlen
register = int(addr)
if register == 0:
return 0
while not register & 1:
prefixlen -= 1
register = register >> 1
if register != 2**prefixlen - 1:
raise ValueError("{} does not appear to be a netmask".format(addr))
return prefixlen
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds ipaddress_to_prefixlen, but cloud-init already provides ipv6_mask_to_net_prefix in cloudinit.net.network_state, which handles both prefix-length strings (e.g. '64') and IPv6 netmask notation (e.g. 'ffff:ffff:ffff::') and validates contiguity. Reusing the shared helper would reduce duplicated logic and keep netmask parsing consistent across the codebase.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 26, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@jplitza
Copy link
Copy Markdown
Author

jplitza commented Mar 26, 2026

I have read the CLA Document and I hereby sign the CLA

vyosbot added a commit to vyos/vyos-cla-signatures that referenced this pull request Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants