@@ -2512,6 +2512,10 @@ func calculateStatelessNATIP(sourceIP, sourceSubnet, natPoolStart netip.Addr) (n
25122512// testNATGatewayConnectivity performs E2E connectivity testing for NAT gateway peering.
25132513// It discovers server IPs, calculates expected NAT IPs, and performs ping/iperf3 tests.
25142514// NOTE: This uses calculateStatelessNATIP which couples to the dataplane NAT algorithm.
2515+ // The function supports both source NAT and destination NAT:
2516+ // - If vpc2NATPool is set: vpc1 pings vpc2 using vpc2's NAT IPs (destination NAT)
2517+ // - If vpc2NATPool is empty: vpc1 pings vpc2's real IPs (source NAT on vpc1 side)
2518+ // vpc1NATPool is not used because source NAT is transparent from the client perspective.
25152519func (testCtx * VPCPeeringTestCtx ) testNATGatewayConnectivity (
25162520 ctx context.Context ,
25172521 vpc1 , vpc2 * vpcapi.VPC ,
@@ -2637,7 +2641,9 @@ func (testCtx *VPCPeeringTestCtx) testNATGatewayConnectivity(
26372641 }
26382642 }
26392643
2640- // Test connectivity: vpc1 -> vpc2 (pinging NAT IP of vpc2 server)
2644+ // Test connectivity: vpc1 -> vpc2
2645+ // If vpc2NATPool is set, ping vpc2's NAT IPs (destination NAT)
2646+ // If vpc2NATPool is empty, ping vpc2's real IPs (source NAT on vpc1 side)
26412647 pings := semaphore .NewWeighted (10 )
26422648 var errors []error
26432649 var errMutex sync.Mutex
@@ -2646,9 +2652,9 @@ func (testCtx *VPCPeeringTestCtx) testNATGatewayConnectivity(
26462652 for _ , serverB := range vpc2Servers {
26472653 destIP := serverIPs [serverB ]
26482654
2649- // Calculate expected NAT IP for destination
2655+ // Calculate expected NAT IP for destination (only if vpc2 has NAT configured)
26502656 natDestIP := destIP
2651- if ! vpc2NATPoolStart .IsUnspecified () {
2657+ if len ( vpc2NATPool ) > 0 && ! vpc2NATPoolStart .IsUnspecified () {
26522658 var err error
26532659 natDestIP , err = calculateStatelessNATIP (destIP , vpc2SubnetStart , vpc2NATPoolStart )
26542660 if err != nil {
@@ -2699,9 +2705,9 @@ func (testCtx *VPCPeeringTestCtx) testNATGatewayConnectivity(
26992705 for _ , serverB := range vpc2Servers {
27002706 destIP := serverIPs [serverB ]
27012707
2702- // Calculate expected NAT IP for destination
2708+ // Calculate expected NAT IP for destination (only if vpc2 has NAT configured)
27032709 natDestIP := destIP
2704- if ! vpc2NATPoolStart .IsUnspecified () {
2710+ if len ( vpc2NATPool ) > 0 && ! vpc2NATPoolStart .IsUnspecified () {
27052711 var err error
27062712 natDestIP , err = calculateStatelessNATIP (destIP , vpc2SubnetStart , vpc2NATPoolStart )
27072713 if err != nil {
@@ -2865,7 +2871,9 @@ func (testCtx *VPCPeeringTestCtx) gatewayPeeringNATTest(ctx context.Context) (bo
28652871 return false , reverts , nil
28662872}
28672873
2868- // Test basic gateway peering with stateful NAT
2874+ // Test basic gateway peering with stateful source NAT
2875+ // Note: Stateful NAT has a limitation where it can only be configured on one side of the peering.
2876+ // This test configures NAT on vpc-01 side only, allowing vpc-01 to reach vpc-02 with source NAT.
28692877func (testCtx * VPCPeeringTestCtx ) gatewayPeeringStatefulNATTest (ctx context.Context ) (bool , []RevertFunc , error ) {
28702878 vpcs := & vpcapi.VPCList {}
28712879 if err := testCtx .kube .List (ctx , vpcs ); err != nil {
@@ -2905,7 +2913,7 @@ func (testCtx *VPCPeeringTestCtx) gatewayPeeringStatefulNATTest(ctx context.Cont
29052913 }
29062914
29072915 vpc1NATCIDR := []string {"192.168.11.0/24" }
2908- vpc2NATCIDR := []string {"192.168.12.0/24" }
2916+ vpc2NATCIDR := []string {} // Empty - no NAT on vpc-02 side (limitation: NAT only on one side)
29092917
29102918 // Configure stateful NAT with custom idle timeout
29112919 statefulNATConfig := & gwapi.PeeringNAT {
@@ -2939,8 +2947,9 @@ func (testCtx *VPCPeeringTestCtx) gatewayPeeringStatefulNATTest(ctx context.Cont
29392947 // Wait for stateful NAT gateway peering to take effect
29402948 time .Sleep (15 * time .Second )
29412949
2942- // Test stateful NAT connectivity with custom function that pings correct NAT IPs
2943- // Note: Stateful NAT uses the same IP translation algorithm as stateless
2950+ // Test stateful NAT connectivity from vpc1 to vpc2
2951+ // vpc1 will present to vpc2 as 192.168.11.x (NAT translation)
2952+ // vpc2 has no NAT, so remains as 10.0.2.x
29442953 if err := testCtx .testNATGatewayConnectivity (ctx , vpc1 , vpc2 , vpc1NATCIDR , vpc2NATCIDR ); err != nil {
29452954 if testCtx .pauseOnFail {
29462955 pauseOnFail ()
0 commit comments