Skip to content

Conversation

@jupdec
Copy link
Contributor

@jupdec jupdec commented Oct 13, 2025

What type of PR is this?
bug

Which issue does this PR fix?:

What does this PR do / Why do we need it?:
Gracefully handle v4 unmanaged ENI on ipv6 node

Testing done on this change:

Ran ipv6 integration tests successfully

dev-dsk-kaposmee-2c-6ef44606 % ./scripts/run-ipv6-integration-tests.sh 
Running tests for amazon-vpc-cni-k8s with the following variables
KUBECONFIG:  /home/kaposmee/.kube/config
CLUSTER_NAME: ipv6-cluster
REGION: us-west-2
ENDPOINT: 
making ginkgo test binaries
mkdir -p /workplace/kaposmee/cni/amazon-vpc-cni-k8s/test/build
find /workplace/kaposmee/cni/amazon-vpc-cni-k8s/test/ -name '*suite_test.go' -type f  | xargs dirname  | xargs ginkgo build

------------------------------
[AfterSuite] 
/workplace/kaposmee/cni/amazon-vpc-cni-k8s/test/integration/ipv6/pod_v6_networking_suite_test.go:54
  STEP: deleting test namespace @ 10/14/25 21:58:48.609
  STEP: update environment variables map[AWS_VPC_ENI_MTU:9001 AWS_VPC_K8S_CNI_VETHPREFIX:eni], remove map[WARM_ENI_TARGET:{} WARM_IP_TARGET:{}] @ 10/14/25 21:59:04.728
  STEP: getting the aws-node daemon set in namespace kube-system @ 10/14/25 21:59:04.728
  STEP: updating the daemon set with new environment variable @ 10/14/25 21:59:04.73
[AfterSuite] PASSED [16.154 seconds]
------------------------------

Ran 8 of 8 Specs in 540.623 seconds
SUCCESS! -- 8 Passed | 0 Failed | 0 Pending | 0 Skipped
PASS

Will this PR introduce any new dependencies?:

Will this break upgrades or downgrades? Has updating a running cluster been tested?:

Does this change require updates to the CNI daemonset config files to work?:

No

Does this PR introduce any user-facing change?:


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@jupdec jupdec marked this pull request as ready for review October 13, 2025 23:56
@jupdec jupdec requested a review from a team as a code owner October 13, 2025 23:56
@jaydeokar jaydeokar added this to the v1.20.5 milestone Oct 21, 2025
@jaydeokar jaydeokar requested a review from Copilot October 29, 2025 19:41
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a bug where cross-VPC IPv4-only ENIs fail to initialize on IPv6-enabled nodes by making getCIDR return nil instead of an error when encountering 404 Not Found responses.

Key changes:

  • Modified getCIDR function to return *net.IPNet instead of net.IPNet and handle 404 errors gracefully by returning nil
  • Updated GetSubnetIPv4CIDRBlock and GetSubnetIPv6CIDRBlocks return types to *net.IPNet
  • Added nil checks in getENIMetadata to handle cases where IPv6 CIDR blocks are not available
  • Added comprehensive test coverage for the cross-VPC ENI scenario

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
pkg/awsutils/imds.go Changed getCIDR to return pointer and handle 404 errors gracefully; updated method signatures
pkg/awsutils/imds_test.go Updated tests to work with pointer return types
pkg/awsutils/awsutils.go Added nil checks for IPv6 CIDR and removed unused isNotFoundError function
pkg/awsutils/awsutils_test.go Added comprehensive test case for cross-VPC ENI with IPv6 enabled nodes
Comments suppressed due to low confidence (1)

pkg/awsutils/awsutils.go:713

  • Potential nil pointer dereference. Since GetSubnetIPv4CIDRBlock now returns *net.IPNet, it can return nil on 404 errors. The code should check if cidr != nil before calling cidr.String() on line 713, similar to the nil check added for IPv6 CIDR on lines 742-744.
		cidr, err := cache.imds.GetSubnetIPv4CIDRBlock(ctx, eniMAC)
		if err != nil {
			awsAPIErrInc("GetSubnetIPv4CIDRBlock", err)
			return ENIMetadata{}, err
		}

		subnetV4Cidr = cidr.String()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1169 to 1193
// isNotFoundError checks if the error is a 404 Not Found error
func isNotFoundError(err error) bool {
if err == nil {
return false
}

// Check for HTTP status code 404
type httpStatusCoder interface {
HTTPStatusCode() int
}
if httpErr, ok := err.(httpStatusCoder); ok && httpErr.HTTPStatusCode() == 404 {
return true
}

// Check for error code "NotFound"
type errorCoder interface {
ErrorCode() string
}
if codeErr, ok := err.(errorCoder); ok && codeErr.ErrorCode() == "NotFound" {
return true
}

return false
}

Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

The isNotFoundError function appears to be unused and duplicates functionality already provided by the existing IsNotFound function in pkg/awsutils/imds.go (line 655). This creates code duplication and potential maintenance issues. Consider removing this function.

Suggested change
// isNotFoundError checks if the error is a 404 Not Found error
func isNotFoundError(err error) bool {
if err == nil {
return false
}
// Check for HTTP status code 404
type httpStatusCoder interface {
HTTPStatusCode() int
}
if httpErr, ok := err.(httpStatusCoder); ok && httpErr.HTTPStatusCode() == 404 {
return true
}
// Check for error code "NotFound"
type errorCoder interface {
ErrorCode() string
}
if codeErr, ok := err.(errorCoder); ok && codeErr.ErrorCode() == "NotFound" {
return true
}
return false
}

Copilot uses AI. Check for mistakes.
imdsIPv6s, err := cache.imds.GetIPv6s(ctx, eniMAC)
if err != nil {
awsAPIErrInc("GetIPv6s", err)
return ENIMetadata{}, err
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

[nitpick] The error handling logic at line 750 is inconsistent with the pattern used for GetSubnetIPv6CIDRBlocks. For GetIPv6s, errors are returned immediately, while GetSubnetIPv6CIDRBlocks errors were previously handled but are now followed by a nil check. Consider maintaining consistency by continuing execution after GetIPv6s errors in case some ENIs have IPv6 CIDRs but no IPv6 addresses assigned.

Suggested change
return ENIMetadata{}, err
// Continue execution: some ENIs may have IPv6 CIDRs but no IPv6 addresses assigned
ec2ip6s = []ec2types.NetworkInterfaceIpv6Address{}

Copilot uses AI. Check for mistakes.
imdsIPv6s, err := cache.imds.GetIPv6s(ctx, eniMAC)
if err != nil {
awsAPIErrInc("GetIPv6s", err)
return ENIMetadata{}, err
Copy link
Collaborator

@jaydeokar jaydeokar Oct 30, 2025

Choose a reason for hiding this comment

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

Can you remove this line ? Even IPv6s will be missing from an IPv4 ENI

Copy link
Collaborator

@jaydeokar jaydeokar left a comment

Choose a reason for hiding this comment

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

lgtm

@jaydeokar jaydeokar requested a review from Copilot November 1, 2025 00:05
@jaydeokar jaydeokar merged commit 8a4c9c1 into aws:master Nov 1, 2025
11 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

pkg/awsutils/awsutils.go:713

  • Potential nil pointer dereference. The function GetSubnetIPv4CIDRBlock now returns *net.IPNet and can return nil when a 404 error occurs (as seen in the updated getCIDR implementation). This code should check if cidr != nil before calling .String(), similar to how the IPv6 case is handled at lines 742-744.
		subnetV4Cidr = cidr.String()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants