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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions ecs-agent/utils/netlinkwrapper/netlink_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type NetLink interface {
RouteList(link netlink.Link, family int) ([]netlink.Route, error)
LinkByIndex(index int) (netlink.Link, error)
LinkList() ([]netlink.Link, error)
RouteAdd(route *netlink.Route) error
RouteDel(route *netlink.Route) error
}

type netLink struct{}
Expand Down Expand Up @@ -56,3 +58,11 @@ func (nl *netLink) LinkByIndex(index int) (netlink.Link, error) {
func (nl *netLink) LinkList() ([]netlink.Link, error) {
return netlink.LinkList()
}

func (nl *netLink) RouteAdd(route *netlink.Route) error {
return netlink.RouteAdd(route)
}

func (nl *netLink) RouteDel(route *netlink.Route) error {
return netlink.RouteDel(route)
}
7 changes: 7 additions & 0 deletions ecs-init/engine/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ type credentialsProxyRoute interface {
Remove() error
}

// Provides methods to create routes for Task Metadata Server access from the host for
// IPv6-only hosts.
type tmdsRouteManagerForIPv6Only interface {
CreateRoute() error
RemoveRoute() error
}

type ipv6RouterAdvertisements interface {
Disable() error
}
51 changes: 51 additions & 0 deletions ecs-init/engine/dependencies_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 28 additions & 12 deletions ecs-init/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/aws/amazon-ecs-agent/ecs-init/exec/iptables"
"github.com/aws/amazon-ecs-agent/ecs-init/exec/sysctl"
"github.com/aws/amazon-ecs-agent/ecs-init/gpu"
"github.com/aws/amazon-ecs-agent/ecs-init/routes"

log "github.com/cihub/seelog"
ctrdapparmor "github.com/containerd/containerd/pkg/apparmor"
Expand Down Expand Up @@ -65,11 +66,12 @@ func dockerError(err error) error {

// Engine contains methods invoked when ecs-init is run
type Engine struct {
downloader downloader
loopbackRouting loopbackRouting
credentialsProxyRoute credentialsProxyRoute
ipv6RouterAdvertisements ipv6RouterAdvertisements
nvidiaGPUManager gpu.GPUManager
downloader downloader
loopbackRouting loopbackRouting
credentialsProxyRoute credentialsProxyRoute
tmdsRoutesForIPv6OnlyInstance tmdsRouteManagerForIPv6Only
ipv6RouterAdvertisements ipv6RouterAdvertisements
nvidiaGPUManager gpu.GPUManager
}

type TerminalError struct {
Expand Down Expand Up @@ -101,12 +103,17 @@ func New() (*Engine, error) {
if err != nil {
return nil, err
}
tmdsIPv6OnlyRouteManager, err := routes.NewTMDSRouteManagerForIPv6Only(iptables.CredentialsProxyIpAddress)
if err != nil {
return nil, err
}
return &Engine{
downloader: downloader,
loopbackRouting: loopbackRouting,
credentialsProxyRoute: credentialsProxyRoute,
ipv6RouterAdvertisements: ipv6RouterAdvertisements,
nvidiaGPUManager: gpu.NewNvidiaGPUManager(),
downloader: downloader,
loopbackRouting: loopbackRouting,
credentialsProxyRoute: credentialsProxyRoute,
tmdsRoutesForIPv6OnlyInstance: tmdsIPv6OnlyRouteManager,
ipv6RouterAdvertisements: ipv6RouterAdvertisements,
nvidiaGPUManager: gpu.NewNvidiaGPUManager(),
}, nil
}

Expand Down Expand Up @@ -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")

err = e.tmdsRoutesForIPv6OnlyInstance.CreateRoute()
if err != nil {
return engineError("could not create routes for task metadata server", err)
}
// Add the rerouting netfilter rule for credentials endpoint
log.Info("pre-start: creating credentials proxy route")
err = e.credentialsProxyRoute.Create()
Expand Down Expand Up @@ -338,8 +351,11 @@ func (e *Engine) PostStop() error {
log.Info("Cleaning up the credentials endpoint setup for Amazon Elastic Container Service Agent")
err := e.loopbackRouting.RestoreDefault()

// Ignore error from Remove() as the netfilter might never have been
// added in the first place
log.Info("Cleaning up any routes added for TMDS access on IPv6-only instances")
if ipv6OnlyRouteError := e.tmdsRoutesForIPv6OnlyInstance.RemoveRoute(); ipv6OnlyRouteError != nil {
log.Warn("Error when removing TMDS routes for IPv6-only instances: %v", ipv6OnlyRouteError)
}
// Ignore error from Remove() as the netfilter might never have been added in the first place
e.credentialsProxyRoute.Remove()
return err
}
Expand Down
Loading
Loading