Skip to content

Route for TMDS access on host mode on IPv6-only instances #4633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025

Conversation

amogh09
Copy link
Contributor

@amogh09 amogh09 commented May 9, 2025

Summary

Task Metadata Server (TMDS) is not reachable from host network on IPv6-only instances. Calls fail with Couldn't connect to server error.

[ec2-user@ipv6only ~]$ curl http://169.254.170.2/v4/9cb75cbe-b07d-419c-b83b-3d0d36e24b17
curl: (7) Failed to connect to 169.254.170.2 port 80 after 0 ms: Couldn't connect to server

On IPv4-compatible instances, TMDS access from host network works based on an iptables PREROUTING table rule to redirect traffic destined to 169.254.170.2:80 to 127.0.0.1:51679. However, on an IPv6-only instance there are no IPv4 routes at all which causes the calls to fail even before they hit the PREROUTING table rule.

This change solves this problem by creating a route for TMDS traffic to route it to loopback interface. The route is created and cleaned up by ecs-init during pre-start and post-stop phases, respectively. The route is created only on IPv6-only instances. The created route is an equivalent of ip route add 169.254.170.2/32 dev lo.

Implementation details

  • A new tmdsRouteManagerForIPv6Only interface is added as a new dependency of ecs-init's engine. The interface provides methods to create and remove the route for TMDS access on host network on IPv6-only instances.
  • engine's pre-start and post-stop methods are updated to call tmdsRouteManagerForIPv6Only's CreateRoute and RemoveRoute methods, respectively.
  • type TMDSRouteManagerForIPv6Only struct is added that implements tmdsRouteManagerForIPv6Only. It's CreateRoute and RemoveRoute methods both check if the instance is IPv6-only and create/remove the route using netlink library if so. To check IPv6-only status of the instance, the methods use HasDefaultRoute function from ecs-agent/utils/net package. So, this change makes ecs-init depend on ecs-agent module for the first time. This change also makes netlink a dependency of ecs-init.

Testing

Built ecs-init rpm and ran it on an IPv6-only instance. Observed the following.

  1. 169.254.170.2 dev lo scope link is created when ecs-init starts.
  2. TMDS is reachable from the host network at 169.254.170.2 address.
  3. The route is deleted when ecs-init stops.
[ec2-user@ipv6only ~]$ sudo systemctl stop ecs
[ec2-user@ipv6only ~]$ ip route show | grep 169.254.170.2
[ec2-user@ipv6only ~]$ sudo systemctl start ecs
[ec2-user@ipv6only ~]$ ip route show | grep 169.254.170.2
169.254.170.2 dev lo scope link
[ec2-user@ipv6only ~]$ curl 169.254.170.2
404 page not found
[ec2-user@ipv6only ~]$ sudo systemctl stop ecs
[ec2-user@ipv6only ~]$ ip route show | grep 169.254.170.2
[ec2-user@ipv6only ~]$

Did the same on a dual-stack instance and observed the following.

  1. No route for 169.254.170.2 is created when ecs-init starts.
ip-10-0-0-23 ❱ ip route show | grep 169.254.170.2
ip-10-0-0-23 ❱ sudo systemctl start ecs
ip-10-0-0-23 ❱ ip route show | grep 169.254.170.2
ip-10-0-0-23 ❱

New tests cover the changes: yes

Description for the changelog

Enhancement: Create a route for TMDS access on host mode on IPv6-only instances.

Additional Information

Does this PR include breaking model changes? If so, Have you added transformation functions?

No

Does this PR include the addition of new environment variables in the README?

No

Licensing

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

@amogh09 amogh09 requested a review from a team as a code owner May 9, 2025 23:13
@amogh09 amogh09 force-pushed the ipv6-host-route branch from 4f48710 to ff54fa5 Compare May 11, 2025 03:03
@amogh09 amogh09 changed the title Ipv6 host route Route for TMDS access on host mode on IPv6-only instances May 11, 2025
@amogh09 amogh09 enabled auto-merge (squash) May 14, 2025 16:13
Copy link
Contributor

@singholt singholt left a comment

Choose a reason for hiding this comment

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

minor feedback, with 1 overall suggestion about having this in the shared library

@@ -136,6 +143,12 @@ func (e *Engine) PreStart() error {
if err != nil {
return engineError("could not disable ipv6 router advertisements", err)
}
// Add a local route for TMDS if there are no IPv4 default routes
log.Info("pre-start: adding routes for TMDS access on IPv6-only host if applicable")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
log.Info("pre-start: adding routes for TMDS access on IPv6-only host if applicable")
log.Info("Pre-start: adding routes for TMDS access on IPv6-only host if applicable")


netutils "github.com/aws/amazon-ecs-agent/ecs-agent/utils/net"
"github.com/aws/amazon-ecs-agent/ecs-agent/utils/netlinkwrapper"
"github.com/cihub/seelog"
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: seelog goes into the third block.

return &TMDSRouteManagerForIPv6Only{nl: netlinkwrapper.New(), tmdsAddr: addr}, nil
}

// Creates a route to route TMDS traffic to loopback interface.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: godoc starts with the element it describes: https://go.dev/blog/godoc, applicable across the PR.

return nil
}

seelog.Info("Detected IPv6-only instance: adding route to route TMDS traffic to loopback")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
seelog.Info("Detected IPv6-only instance: adding route to route TMDS traffic to loopback")
seelog.Info("Detected IPv6-only instance: adding route to direct TMDS traffic to loopback")

minor suggestion, "... route to route ... " can be confusing.

@@ -0,0 +1,131 @@
// Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be useful to have this in the shared library

Copy link
Contributor

Choose a reason for hiding this comment

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

also update the copyright header btw :)


if err := nl.RouteAdd(route); err != nil {
if os.IsExist(err) {
seelog.Infof("Route %+v already exists", route)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
seelog.Infof("Route %+v already exists", route)
seelog.Debugf("Route %+v already exists", route)

minor suggestion, to reduce log noise

// Get the loopback interface.
lo, err := nl.LinkByName("lo")
if err != nil {
return nil, fmt.Errorf("error getting lo interface: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return nil, fmt.Errorf("error getting lo interface: %v", err)
return nil, fmt.Errorf("error getting lo interface: %w", err)

to facilitate unwrapping as needed.

@amogh09 amogh09 merged commit f507a39 into aws:dev May 14, 2025
40 checks passed
xxx0624 pushed a commit to xxx0624/amazon-ecs-agent that referenced this pull request May 15, 2025
@danehlim danehlim mentioned this pull request May 20, 2025
timj-hh pushed a commit to timj-hh/amazon-ecs-agent that referenced this pull request Jul 19, 2025
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.

4 participants