systemvm: ipv6 fw_input — accept return traffic from established,rela…#13173
Conversation
|
Congratulations on your first Pull Request and welcome to the Apache CloudStack community! If you have any issues or are unsure about any anything please check our Contribution Guide (https://github.com/apache/cloudstack/blob/main/CONTRIBUTING.md)
|
0a11f6e to
992fbf5
Compare
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@agronaught |
|
any chance of also getting this backported into the next 4.22 release ? |
@agronaught |
|
thank you, will do.
…On Mon, May 18, 2026 at 8:18 PM Wei Zhou ***@***.***> wrote:
*weizhouapache* left a comment (apache/cloudstack#13173)
<#13173 (comment)>
any chance of also getting this backported into the next 4.22 release ?
another pull request ?
@agronaught <https://github.com/agronaught>
you can rebase your branch with 4.22 branch.
all 4.22 commits will be merged into main branch
—
Reply to this email directly, view it on GitHub
<#13173 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEFA4QS6IRAJ32OAMQPCUT43LPOBAVCNFSM6AAAAACZB3H7PGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DINZWGY3DMNJUGU>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
--
Teach your kids Science, or somebody else will :/
***@***.***
***@***.*** ***@***.***>
callsign: vk2vjb
|
992fbf5 to
8dcc070
Compare
|
rebased to 4.22 |
|
@blueorangutan package |
|
@weizhouapache a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 4.22 #13173 +/- ##
============================================
- Coverage 17.67% 17.67% -0.01%
+ Complexity 15788 15785 -3
============================================
Files 5922 5922
Lines 533123 533123
Branches 65201 65201
============================================
- Hits 94242 94230 -12
- Misses 428237 428248 +11
- Partials 10644 10645 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✖️ debian ✔️ suse15. SL-JID 17892 |
winterhazel
left a comment
There was a problem hiding this comment.
@agronaught thanks for the pull request. The code looks good.
I think that we can restore the changes removed in the 2nd commit of #10970 to accept IPv6 packets from related/established connections going to the virtual router even for non-routed networks. I only removed the rule from the INPUT chain because it was not required to address the issue I was facing at the time, but can't think of a reason for not having it.
Sounds fair. |
@agronaught yes, please do. |
In most cases, CloudStack VRs simply forward traffic to guest VMs and do not expose public services themselves. That is why we originally did not add the rule It was my suggestion to apply the changes introduced in the 2nd commit of PR #10970. At that time, I did not consider BGP sessions as a use case. I agree that we could revert the changes introduced here: That might resolve the issue without requiring the changes proposed in this PR. The IPv4 rules are correct. When I developed the Dynamic Routing feature, I explicitly added the rules for routed networks and routed VPCs: So the issue appears to be specific to the IPv6 rules. |
…olated Per upstream review feedback on apache#13173: drop the is_routed() guard on fw_router_routing_v6() so non-routed Isolated v6 networks also accept established/related return traffic to the VR. Keep the is_vpc() guard (VPC has its own firewall path via fw_vpcrouter_routing). Scope stays narrow: only the established/related rules. v4's service-port rules (tcp/3922, tcp/8080) are not mirrored into the v6 INPUT chain. Tested on staging (4.22.0.0): - Routed Isolated v6 (Filtered offering): BGP v6 sessions reach Established, eth2 established/related rule counter active (81 packets / 9893 bytes). - Non-routed Isolated v6 (DualStack offering with VirtualRouter + SourceNat): fw_input contains lo/eth2/eth0 established/related rules identical to the routed case; counter activity on eth2 (66 packets / 8369 bytes) confirms the rule is reached. Signed-off-by: Jason Ball <jball@resetdata.com>
|
Done — pushed b89599b. Tested on ACS 4.22.0.0 staging: Routed Isolated v6 (IsolatedV6RoutedFiltered offering): Non-routed Isolated v6 (DualStack offering, VirtualRouter + Scope kept narrow per your suggestion: only the established/related Note: fw_input ends up with the rules duplicated (lo + eth2 appear |
|
@agronaught do not make other changes |
missed this. |
The IPv6 fw_input chain currently accepts only ICMPv6 control traffic and policy=drop everything else. Return traffic for VR-initiated v6 connections (e.g. BGP SYN-ACKs from upstream peers) is silently dropped. PR apache#10970 added the equivalent rule to the v6 FORWARD chain but removed it from INPUT in its second commit. This restores it at chain creation, so it applies uniformly to all v6 input-hook chains (routed Isolated, non-routed Isolated, etc.). Tested on ACS 4.22.0.0 staging: - Routed Isolated v6 (IsolatedV6RoutedFiltered offering): BGP v6 sessions reach Established, tenant /64 advertised upstream. - Non-routed Isolated v6 (DualStack with VirtualRouter + SourceNat): fw_input contains the established/related accept rule and accepts return traffic. Resulting fw_input on both shapes: chain fw_input { type filter hook input priority filter; policy drop; icmpv6 type { ... } accept ct state established,related accept } Fixes: apache#13171 Refs: apache#10970 Co-authored-by: Bryan Lima <[email protected]> Signed-off-by: Jason Ball <jball@resetdata.com>
b89599b to
dd7e103
Compare
|
Tested and confirmed working — replaced my two earlier commits with your diff (dd7e103). Routed Isolated v6: BGP v6 reaches Established with both peers; PfxRcd:1, PfxSnt:2. Non-routed Isolated v6 (DualStack offering w/ VirtualRouter + SourceNat): fw_input has the rule from chain creation; tested return traffic flow. Resulting chain on both shapes: Much cleaner than my CsAddress.py approach — single rule, no duplicates from post_config_change re-runs. Thanks for the pointer to #10970's 2nd commit; my fault for not finding that during the original investigation. |
@agronaught @winterhazel thanks for the good point. |
|
tested ok routed network VR routed VPC VR |
|
Awesome work, congrats on your first merged pull request! |
This PR adds the IPv6 equivalent of
fw_router_routing()to the systemvm Virtual Router's network configuration, so that return traffic for VR-initiated IPv6 connections (BGP to upstream PE peers, NTP, DNS lookups, etc.) is allowed back through theip6_firewall fw_inputchain.Problem
The systemvm VR's nftables
ip6 ip6_firewall fw_inputchain is created withpolicy=dropand only ICMPv6 accept rules. The IPv4 INPUT chain has the equivalentiifname "eth2" ct state established,related acceptrule (added byfw_router_routing()inCsAddress.py); the IPv6 path has no such rule.Effect: any v6 connection the VR itself initiates outbound has its return traffic silently dropped at the v6 INPUT hook before TCP processes it. For Isolated IPv6 ROUTED networks this is fatal — BGP IPv6 sessions cannot reach
Established, tenant/64prefixes are never advertised upstream, and VMs in the network are unreachable from the IPv6 internet.#10970 added the equivalent rule to the FORWARD chain (covering tenant VM return traffic) but explicitly removed it from the INPUT chain in its second commit. This PR completes that fix for VR-originated traffic.
Behavioural change
Before this PR, IPv6 BGP sessions from VRs in
IsolatedV6RoutedFiltered(and similar Routed v6) network offerings stay inConnectstate indefinitely. After this PR, sessions reachEstablishedwithin seconds of VR start and prefix advertisements work normally.The change is additive and behind the existing
is_routed()/is_vpc()gating — only routed, non-VPC networks see new INPUT rules. No change for existing v4 paths, v4 NATted networks, or VPC networks.Fixes: #13171
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Justifying Major: any operator wanting to ship the
IsolatedV6RoutedFilteredoffering (or any v6 Routed isolated network withFirewallservice) for production tenant workloads is blocked. Workaround requires per-VRnftinjection that wipes on every tenant FW rule change, making the offering unusable as a customer product without a downstream patch like this one.Screenshots (if appropriate)
N/A — kernel-level firewall change.
How Has This Been Tested?
Verified end-to-end on Apache CloudStack 4.22.0.0, KVM hypervisor (Ubuntu 24.04 hosts), with:
/48)IsolatedV6RoutedFilteredofferingBefore the patch:
vtysh -c "show bgp ipv6 unicast summary"
Neighbor State/PfxRcd
2400:88e0:ffff:258::2 Connect 0
2400:88e0:ffff:258::3 Connect 0
Hypervisor-side packet capture on the underlay confirms PE responds with SYN-ACK, but the VR's TCP stack never delivers it to FRR. Kernel
TCPMD5*counters stay at zero — drop happens at netfilter before TCP processes the segment. Inside the VR:$ nft list table ip6 ip6_firewall
table ip6 ip6_firewall {
chain fw_input {
type filter hook input priority filter; policy drop;
icmpv6 type { ... } accept
}
...
}
No
ct state established,related acceptrule.After the patch:
vtysh -c "show bgp ipv6 unicast summary"
Neighbor State/PfxRcd
2400:88e0:ffff:258::2 Established 1
2400:88e0:ffff:258::3 Established 1
fw_inputnow includes the new rule with active counters:iifname "eth2" ct state established,related counter packets ... bytes ... accept
Verified end-to-end: SSH from public IPv6 internet to a VM inside the v6-routed network succeeds. Reachability survives subsequent tenant firewall rule updates (the rule is rebuilt from
nft_ipv6_fwon everyIpTablesExecutor.process()cycle).How did you try to break this feature and the system with this change?
cmk createIpv6FirewallRule/deleteIpv6FirewallRulerepeatedly after the patch.IpTablesExecutor.process()flushes and rebuilds the v6 table each time; the new INPUT rule is re-emitted on every cycle because it's now innft_ipv6_fw. Counters resume; BGP stays Established.cmk rebootRouter). After the reboot pulls freshcloud-scripts.tgz, the patchedCsAddress.pyruns in the rebuilt VR and the rule is in place from boot. BGP establishes within ~30s of VR ready.is_routed()gating means standard Isolated v4 networks and VPC networks see no new rules in either chain — no behaviour change for them.eth2reference and per-VR counter), with no cross-tenant traffic leakage.Tested with both single-tenant and multi-tenant network deployments. Validated the substrate change on ACS 4.22.0.0; same code path exists in
4.20branch HEAD per inspection.