You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As it stands now, on KVM hypervisors, IPv6 guest network traffic is routed through a Virtual Router whose upstream global unicast address acts as the next-hop gateway. Unlike IPv4, which relies on ARP and existing bridge mechanics, IPv6 requires explicit kernel routes (ip -6 route add /64 via ) to be present on the hypervisor itself. Today these routes are either installed manually or left to the operator, meaning any VR lifecycle event — start, stop, or live migration — silently leaves the hypervisor routing table in an inconsistent state. Guests on IPv6-only or dual-stack networks lose connectivity until the routes are restored by hand.
For our infastructure we currently managing this externaly which works (most of the time).
We were thinking if this could be a new feature that will be incorporated in cloudstack out of the box and we start implementing a new plugin (cloud-plugin-network-kvm-ipv6-vr-routes) that subscribes to three internal MessageBus topics published from VirtualNetworkApplianceManagerImpl — RouterStarted, RouterStopped, and RouterMigrated — and in response sends a new agent command (SetupIpv6RoutesCommand) to the KVM hypervisor. The management server side resolves the guest network prefixes and the VR's upstream IPv6 address from the database and includes both in the command, so the KVM agent performs a straightforward ip -6 route add|del with no kernel probing required. Live migration is handled correctly for both the success path (remove from source, install on destination) and the failure/revert path (undo partial state on the failed destination). Two global configuration knobs control the feature: router.ipv6.persist.routes optionally writes systemd-networkd drop-in files so routes survive hypervisor reboots, and router.ipv6.extra.prefixes allows injecting additional prefixes beyond those derived from network CIDRs.
Two global configuration knobs control the feature: router.ipv6.persist.routes optionally writes systemd-networkd drop-in files so routes survive hypervisor reboots, and router.ipv6.extra.prefixes allows injecting additional prefixes beyond those derived from network CIDRs.
The design deliberately keeps the plugin non-invasive: the three _messageBus.publish() calls added to VirtualNetworkApplianceManagerImpl are each wrapped in a try/catch so any failure in the IPv6 layer cannot propagate back and disrupt VR operations. The plugin is a complete no-op on deployments without IPv6 guest networks — buildRouteEntries() returns an empty list and no agent command is ever sent.
The natural next step is to expose route provisioning as an on-demand management API. A syncRouterIpv6Routes command, scoped to the Admin role, would allow operators to re-provision routes for a specific Virtual Router without restarting it — the primary recovery scenario being a KVM hypervisor reboot, after which all in-memory kernel routes are lost. Since SetupIpv6RoutesCommand is already idempotent, the API would simply trigger the same setupRoutesForRouter path used by the lifecycle events, with no additional risk. We have deliberately left this out of the current scope to keep the initial contribution focused, but consider it a natural follow-up once the core plugin lands.
We are sharing this as a starting point for discussion; in particular we would welcome feedback on whether the MessageBus approach is preferred over a dedicated VirtualRouterElement hook, and whether an on-demand syncRouterIpv6Routes API should be included in scope.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello all, i hope you are doing well.
As it stands now, on KVM hypervisors, IPv6 guest network traffic is routed through a Virtual Router whose upstream global unicast address acts as the next-hop gateway. Unlike IPv4, which relies on ARP and existing bridge mechanics, IPv6 requires explicit kernel routes (ip -6 route add /64 via ) to be present on the hypervisor itself. Today these routes are either installed manually or left to the operator, meaning any VR lifecycle event — start, stop, or live migration — silently leaves the hypervisor routing table in an inconsistent state. Guests on IPv6-only or dual-stack networks lose connectivity until the routes are restored by hand.
For our infastructure we currently managing this externaly which works (most of the time).
We were thinking if this could be a new feature that will be incorporated in cloudstack out of the box and we start implementing a new plugin (cloud-plugin-network-kvm-ipv6-vr-routes) that subscribes to three internal MessageBus topics published from VirtualNetworkApplianceManagerImpl — RouterStarted, RouterStopped, and RouterMigrated — and in response sends a new agent command (SetupIpv6RoutesCommand) to the KVM hypervisor. The management server side resolves the guest network prefixes and the VR's upstream IPv6 address from the database and includes both in the command, so the KVM agent performs a straightforward ip -6 route add|del with no kernel probing required. Live migration is handled correctly for both the success path (remove from source, install on destination) and the failure/revert path (undo partial state on the failed destination). Two global configuration knobs control the feature: router.ipv6.persist.routes optionally writes systemd-networkd drop-in files so routes survive hypervisor reboots, and router.ipv6.extra.prefixes allows injecting additional prefixes beyond those derived from network CIDRs.
Two global configuration knobs control the feature: router.ipv6.persist.routes optionally writes systemd-networkd drop-in files so routes survive hypervisor reboots, and router.ipv6.extra.prefixes allows injecting additional prefixes beyond those derived from network CIDRs.
The design deliberately keeps the plugin non-invasive: the three _messageBus.publish() calls added to VirtualNetworkApplianceManagerImpl are each wrapped in a try/catch so any failure in the IPv6 layer cannot propagate back and disrupt VR operations. The plugin is a complete no-op on deployments without IPv6 guest networks — buildRouteEntries() returns an empty list and no agent command is ever sent.
The natural next step is to expose route provisioning as an on-demand management API. A syncRouterIpv6Routes command, scoped to the Admin role, would allow operators to re-provision routes for a specific Virtual Router without restarting it — the primary recovery scenario being a KVM hypervisor reboot, after which all in-memory kernel routes are lost. Since SetupIpv6RoutesCommand is already idempotent, the API would simply trigger the same setupRoutesForRouter path used by the lifecycle events, with no additional risk. We have deliberately left this out of the current scope to keep the initial contribution focused, but consider it a natural follow-up once the core plugin lands.
We are sharing this as a starting point for discussion; in particular we would welcome feedback on whether the MessageBus approach is preferred over a dedicated VirtualRouterElement hook, and whether an on-demand syncRouterIpv6Routes API should be included in scope.
Kind regards,
Beta Was this translation helpful? Give feedback.
All reactions