Skip to content

systemvm: emit IPv6 prefix block for redundant VPC VRs in radvd.conf#13127

Open
jeanvetorello wants to merge 1 commit intoapache:4.22from
jeanvetorello:ipv6-redundant-with-ipv6-4.22
Open

systemvm: emit IPv6 prefix block for redundant VPC VRs in radvd.conf#13127
jeanvetorello wants to merge 1 commit intoapache:4.22from
jeanvetorello:ipv6-redundant-with-ipv6-4.22

Conversation

@jeanvetorello
Copy link
Copy Markdown
Contributor

Description

Fixes #13121 — IPv6 SLAAC broken on Redundant VPC Virtual Router due to a missing
Prefix Information Option (PIO) in radvd.conf.

In CsVpcGuestNetwork.add_radvd_conf(), the prefix { ... } block was emitted
only when router_guest_ip6 == router_guest_ip6_gateway. That condition is true
for non-redundant VRs (where the router itself is the gateway), but never for
redundant VRs:

As a result, on a redundant VPC tier the radvd daemon was started but advertised
RAs without a Prefix Information Option, so guest VMs could only configure
link-local fe80:: addresses and never obtained a global IPv6 via SLAAC.

The fix removes the conditional and always emits the prefix block when radvd is
configured for the tier. This aligns the VPC path with the non-VPC path
(systemvm/debian/opt/cloud/bin/setup/common.sh + radvd.conf.tmpl), which
already emits the prefix block unconditionally.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • build/CI
  • test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Bug Severity

  • BLOCKER
  • [] Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

N/A — config file change.

How Has This Been Tested?

Tested on a VPC with IPv6 enabled and Redundant VR enabled, SystemVM template
based on Debian, SLAAC only (no DHCPv6).

Before the fix:

  • cat /etc/radvd.conf on the primary VR showed the interface ethX { ... }
    block but no prefix section.
  • tcpdump -i ethX -vv 'icmp6 and ip6[40] = 134' showed Router Advertisements
    without a Prefix Information Option.
  • Guest VMs only configured a link-local fe80:: address.

After the fix:

  • /etc/radvd.conf contains the expected
    prefix <gateway>/64 { AdvOnLink on; AdvAutonomous on; }; block.
  • tcpdump confirms RAs include the Prefix Information Option.
  • Guest VMs auto-configure global IPv6 addresses via SLAAC.
  • Failover from primary to backup still works: backup VR keeps radvd disabled
    via CsRedundant._disable_radvd, so no duplicate RAs are emitted; on
    promotion, radvd is started with the correct configuration.

Non-redundant VPC VRs are unchanged (router_guest_ip6 == router_guest_ip6_gateway
in that case, which already produced the same output as the unconditional path).

@weizhouapache
Copy link
Copy Markdown
Member

@jeanvetorello
thanks for creating the PR.

In some cases, the VR is not the gateway, so advertising the SLAAC prefix is not required. One example is Netris, where this change was originally introduced (see #10458).
We should consider two different scenarios where the VR IP is not the gateway IP:

  • Redundant VRs — the configuration is still needed
  • VR is not acting as the gateway — the configuration is not needed

It would be good to clearly distinguish these two cases in the implementation/design.
I will take another look as well.

@weizhouapache weizhouapache self-assigned this May 7, 2026
@weizhouapache
Copy link
Copy Markdown
Member

@jeanvetorello
can you test the change below ?

diff --git a/systemvm/debian/opt/cloud/bin/cs/CsVpcGuestNetwork.py b/systemvm/debian/opt/cloud/bin/cs/CsVpcGuestNetwork.py
index 6f1ec62cd08..cc832c00672 100755
--- a/systemvm/debian/opt/cloud/bin/cs/CsVpcGuestNetwork.py
+++ b/systemvm/debian/opt/cloud/bin/cs/CsVpcGuestNetwork.py
@@ -107,7 +107,7 @@ class CsVpcGuestNetwork(CsDataBag):
             self.conf.append("    AdvSendAdvert on;")
             self.conf.append("    MinRtrAdvInterval 5;")
             self.conf.append("    MaxRtrAdvInterval 15;")
-            if entry['router_guest_ip6'] == entry['router_guest_ip6_gateway']:
+            if entry['router_guest_ip6'] == entry['router_guest_ip6_gateway'] or self.config.is_redundant():
                 self.conf.append("    prefix %s" % full_addr)
                 self.conf.append("    {")
                 self.conf.append("        AdvOnLink on;")

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 17.68%. Comparing base (3e688b0) to head (51ade96).

Additional details and impacted files
@@            Coverage Diff            @@
##               4.22   #13127   +/-   ##
=========================================
  Coverage     17.68%   17.68%           
  Complexity    15792    15792           
=========================================
  Files          5922     5922           
  Lines        533087   533087           
  Branches      65206    65206           
=========================================
  Hits          94269    94269           
  Misses       428176   428176           
  Partials      10642    10642           
Flag Coverage Δ
uitests 3.69% <ø> (ø)
unittests 18.76% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants