Skip to content

Commit 992fbf5

Browse files
author
Jason Ball
committed
systemvm: ipv6 fw_input — accept return traffic from established,related connections
The systemvm Virtual Router's nftables `ip6 ip6_firewall fw_input` chain is created with policy=drop and only ICMPv6 accept rules. The IPv4 INPUT chain has the equivalent `iifname "eth2" ct state established,related accept` rule (added by `fw_router_routing()`); the IPv6 path has no such rule. Effect: any v6 connection the VR itself initiates outbound (BGP to upstream PE peers, NTP, DNS lookups, etc.) has its return traffic silently dropped at the v6 INPUT hook before TCP processes it. For Isolated v6 ROUTED networks this is fatal — BGP IPv6 sessions cannot establish, tenant /64 prefixes are never advertised upstream, and VMs in the network are unreachable from the IPv6 internet. PR #10970 added the equivalent rule to the FORWARD chain only (covering tenant VM return traffic). This commit adds the matching rule to the INPUT chain (covering VR-originated return traffic) by introducing `fw_router_routing_v6()` as the IPv6 mirror of `fw_router_routing()`. Verified end-to-end on ACS 4.22.0.0 KVM: before the patch, v6 BGP sessions stay in `Connect` indefinitely; tcpdump confirms PE responds with SYN-ACK but VR's TCP stack never sees the SYN-ACK (MD5 counters zero — drop happens at netfilter). After the patch, v6 BGP sessions reach `Established` within seconds and remain stable across subsequent tenant firewall rule updates. Fixes: #13171 Signed-off-by: Jason Ball <jball@resetdata.com>
1 parent 5893ba5 commit 992fbf5

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

systemvm/debian/opt/cloud/bin/cs/CsAddress.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ def __init__(self, dev, config):
326326
self.config = config
327327
self.nft_ipv4_fw = config.get_nft_ipv4_fw()
328328
self.nft_ipv4_acl = config.get_nft_ipv4_acl()
329+
self.nft_ipv6_fw = config.get_ipv6_fw()
329330

330331
def setAddress(self, address):
331332
self.address = address
@@ -714,6 +715,22 @@ def fw_router_routing(self):
714715
self.nft_ipv4_fw.append({'type': "", 'chain': 'INPUT',
715716
'rule': "iifname %s ip saddr %s tcp dport 8080 ct state new counter accept" % (self.dev, guestNetworkCidr)})
716717

718+
def fw_router_routing_v6(self):
719+
if self.config.is_vpc() or not self.config.is_routed():
720+
return
721+
# IPv6 INPUT chain defaults — mirror of fw_router_routing() for v4.
722+
# Without these, return traffic for VR-initiated v6 connections (e.g.
723+
# BGP SYN-ACKs to upstream PE peers) is silently dropped by the
724+
# default-DROP policy on fw_input. PR #10970 added the equivalent
725+
# rule to fw_forward only; this completes that fix for INPUT.
726+
self.nft_ipv6_fw.append({'type': "", 'chain': 'fw_input',
727+
'rule': "iifname lo counter accept"})
728+
self.nft_ipv6_fw.append({'type': "", 'chain': 'fw_input',
729+
'rule': "iifname eth2 ct state established,related counter accept"})
730+
if self.get_type() in ["guest"]:
731+
self.nft_ipv6_fw.append({'type': "", 'chain': 'fw_input',
732+
'rule': "iifname %s ct state established,related counter accept" % self.dev})
733+
717734
def fw_vpcrouter_routing(self):
718735
if not self.config.is_vpc() or not self.config.is_routed():
719736
return
@@ -839,6 +856,7 @@ def post_config_change(self, method):
839856
self.fw_vpcrouter()
840857
self.fw_router_routing()
841858
self.fw_vpcrouter_routing()
859+
self.fw_router_routing_v6()
842860
self.fw_dhcpserver()
843861

844862
cmdline = self.config.cmdline()

0 commit comments

Comments
 (0)