Skip to content

mark vpn traffic as exemption for return routes - #14280

Draft
DaanHoogland wants to merge 1 commit into
4.22from
ghi14184-vpnVsSnat-fix
Draft

DaanHoogland wants to merge 1 commit into
4.22from
ghi14184-vpnVsSnat-fix

Conversation

@DaanHoogland

@DaanHoogland DaanHoogland commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR...

Fixes: #14184

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • 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

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

How did you try to break this feature and the system with this change?

@codecov

codecov Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 18.00%. Comparing base (2e63c60) to head (a551b2e).

Additional details and impacted files
@@             Coverage Diff              @@
##               4.22   #14280      +/-   ##
============================================
- Coverage     18.00%   18.00%   -0.01%     
+ Complexity    16219    16218       -1     
============================================
  Files          5936     5936              
  Lines        535716   535716              
  Branches      65596    65596              
============================================
- Hits          96459    96456       -3     
  Misses       428268   428268              
- Partials      10989    10992       +3     
Flag Coverage Δ
uitests 4.02% <ø> (ø)
unittests 19.07% <ø> (-0.01%) ⬇️

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

☔ View full report in Codecov by Harness.
📢 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.

@sonarqubecloud

sonarqubecloud Bot commented Oct 1, 2026

Copy link
Copy Markdown

@skorchir

skorchir commented Oct 1, 2026

Copy link
Copy Markdown

Tested the change on 4.22.1.1 and it fixes #14184. Environment and evidence below.

Environment

  • CloudStack 4.22.1.1, KVM.
  • Two VPCs, one tier and one VM each: vpca 10.10.0.0/16 (vm-a 10.10.1.177), vpcb 10.20.0.0/16 (vm-b 10.20.1.131). IKEv2 site-to-site VPN between them, both sides passive=false, both Connected.
  • Static NAT public IP 10.201.0.104 enabled on vm-a after the VPN connections were created.
  • The patch was applied by editing /opt/cloud/bin/configure.py on vpca's running router (the one line from this PR), then disabling and re-enabling the static NAT so the router regenerated its rules. The router was not rebuilt.

Before (unpatched router), iptables -t nat -S POSTROUTING on vpca's VR

-A POSTROUTING -s 10.10.1.177/32 -o eth1 -j SNAT --to-source 10.201.0.104
-A POSTROUTING -o eth1 -m mark --mark 0x525 -j ACCEPT
-A POSTROUTING -o eth1 -j SNAT --to-source 10.201.0.102

tcpdump -ni eth2 icmp on vpcb's VR while vm-a pings vm-b:

IP 10.201.0.104 > 10.20.1.131: ICMP echo request, id 1257, seq 1, length 64
IP 10.20.1.131 > 10.201.0.104: ICMP echo reply, id 1257, seq 1, length 64

The static-NAT VM reaches the far side with its public address.

After (patched router, static NAT re-applied)

-A POSTROUTING -s 10.10.1.177/32 -o eth1 -m mark ! --mark 0x525 -j SNAT --to-source 10.201.0.104
-A POSTROUTING -o eth1 -m mark --mark 0x525 -j ACCEPT
-A POSTROUTING -o eth1 -j SNAT --to-source 10.201.0.102

Same capture on vpcb's VR:

IP 10.10.1.177 > 10.20.1.131: ICMP echo request, id 1339, seq 1, length 64
IP 10.20.1.131 > 10.10.1.177: ICMP echo reply, id 1339, seq 1, length 64

Private source preserved across the tunnel, with the SNAT rule still ahead of the exemption, so the ordering no longer matters.

Non-tunnel traffic still uses the static NAT. Counters zeroed, then from vm-a: one ping across the tunnel and two HTTPS requests to the internet (iptables -t nat -L POSTROUTING -v -n on vpca's VR):

pkts target  out  source       destination  
2    SNAT    eth1 10.10.1.177  0.0.0.0/0    mark match ! 0x525 to:10.201.0.104
1    ACCEPT  eth1 0.0.0.0/0    0.0.0.0/0    mark match 0x525
2    SNAT    eth1 0.0.0.0/0    0.0.0.0/0    to:10.201.0.102

The two internet connections took the static-NAT SNAT; the tunnel flow took the 0x525 exemption. The VPN connections stayed Connected throughout.

@weizhouapache weizhouapache left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

code lgtm

@weizhouapache

Copy link
Copy Markdown
Member

@DaanHoogland
would you mind changing the PR title to VR: xxxx ?

nowadays, most PRs use the <component>: xxx format. I know there is no strict format for PR titles, but using the <component>: xxx format makes it easier to identify and find related changes in the git history.

This branch has not been deployed

No deployments
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.

VPC VR: static-NAT SNAT rule can precede the site-to-site VPN NAT exemption, so a static-NAT VM's VPN traffic leaves with its public IP

3 participants