Skip to content
Draft
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
9 changes: 9 additions & 0 deletions pkg/aws/ec2/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,12 +752,21 @@ func (c *Client) DeleteNetworkInterface(ctx context.Context, eniID string) error

// AttachNetworkInterface attaches a previously created ENI to an instance
func (c *Client) AttachNetworkInterface(ctx context.Context, index int32, instanceID, eniID string) (string, error) {
return c.AttachNetworkInterfaceWithQueues(ctx, index, instanceID, eniID, nil)
}

// AttachNetworkInterfaceWithQueues attaches a previously created ENI to an instance with optional ENA queue count
func (c *Client) AttachNetworkInterfaceWithQueues(ctx context.Context, index int32, instanceID, eniID string, enaQueueCount *int32) (string, error) {
input := &ec2.AttachNetworkInterfaceInput{
DeviceIndex: aws.Int32(index),
InstanceId: aws.String(instanceID),
NetworkInterfaceId: aws.String(eniID),
}

if enaQueueCount != nil {
input.EnaQueueCount = enaQueueCount
}

c.limiter.Limit(ctx, AttachNetworkInterface)
sinceStart := spanstat.Start()
output, err := c.ec2Client.AttachNetworkInterface(ctx, input)
Expand Down
4 changes: 4 additions & 0 deletions pkg/aws/ec2/mock/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ func (e *API) DeleteNetworkInterface(ctx context.Context, eniID string) error {
}

func (e *API) AttachNetworkInterface(ctx context.Context, index int32, instanceID, eniID string) (string, error) {
return e.AttachNetworkInterfaceWithQueues(ctx, index, instanceID, eniID, nil)
}

func (e *API) AttachNetworkInterfaceWithQueues(ctx context.Context, index int32, instanceID, eniID string, enaQueueCount *int32) (string, error) {
e.rateLimit()
e.delaySim.Delay(AttachNetworkInterface)

Expand Down
1 change: 1 addition & 0 deletions pkg/aws/eni/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type EC2API interface {
GetDetachedNetworkInterfaces(ctx context.Context, tags ipamTypes.Tags, maxResults int32) ([]string, error)
CreateNetworkInterface(ctx context.Context, toAllocate int32, subnetID, desc string, groups []string, allocatePrefixes bool) (string, *eniTypes.ENI, error)
AttachNetworkInterface(ctx context.Context, index int32, instanceID, eniID string) (string, error)
AttachNetworkInterfaceWithQueues(ctx context.Context, index int32, instanceID, eniID string, enaQueueCount *int32) (string, error)
DeleteNetworkInterface(ctx context.Context, eniID string) error
ModifyNetworkInterface(ctx context.Context, eniID, attachmentID string, deleteOnTermination bool) error
AssignPrivateIpAddresses(ctx context.Context, eniID string, addresses int32) ([]string, error)
Expand Down
14 changes: 9 additions & 5 deletions pkg/aws/eni/limits/limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,17 @@ func (l *LimitsGetter) updateFromEC2API(ctx context.Context, api ec2API) error {
ipv6PerAdapter := aws.ToInt32(instanceTypeInfo.NetworkInfo.Ipv6AddressesPerInterface)
hypervisorType := instanceTypeInfo.Hypervisor
isBareMetal := aws.ToBool(instanceTypeInfo.BareMetal)
vCpus := int(aws.ToInt32(instanceTypeInfo.VCpuInfo.DefaultVCpus))
supportsFlexibleEnaQueues := instanceTypeInfo.NetworkInfo.FlexibleEnaQueuesSupport == ec2_types.FlexibleEnaQueuesSupportSupported

l.m[instanceType] = ipamTypes.Limits{
Adapters: int(adapterLimit),
IPv4: int(ipv4PerAdapter),
IPv6: int(ipv6PerAdapter),
HypervisorType: string(hypervisorType),
IsBareMetal: isBareMetal,
Adapters: int(adapterLimit),
IPv4: int(ipv4PerAdapter),
IPv6: int(ipv6PerAdapter),
HypervisorType: string(hypervisorType),
IsBareMetal: isBareMetal,
VCpus: vCpus,
SupportsFlexibleEnaQueues: supportsFlexibleEnaQueues,
}
}
l.lastUpdate = time.Now()
Expand Down
15 changes: 14 additions & 1 deletion pkg/aws/eni/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,9 +521,22 @@
eni.Subnet.CIDR = subnet.CIDR.String()
}

// Determine ENA queue count if the instance supports flexible ENA queues
var enaQueueCount *int32
limits, limitsAvailable = n.getLimits()
if limitsAvailable && limits.SupportsFlexibleEnaQueues && limits.VCpus > 0 {
// Set queue count to match vCPU count, but cap at reasonable maximum
queueCount := limits.VCpus
if queueCount > 128 { // AWS maximum queue count
queueCount = 128
}
enaQueueCount = aws.Int32(int32(queueCount))
scopedLog.Debug("Configuring ENA queues", "queue-count", queueCount, "vcpus", limits.VCpus)

Check failure on line 534 in pkg/aws/eni/node.go

View workflow job for this annotation

GitHub Actions / Lint Source Code

raw keys should not be used (sloglint)
}

var attachmentID string
for range maxAttachRetries {
attachmentID, err = n.manager.api.AttachNetworkInterface(ctx, index, n.node.InstanceID(), eniID)
attachmentID, err = n.manager.api.AttachNetworkInterfaceWithQueues(ctx, index, n.node.InstanceID(), eniID, enaQueueCount)

// The index is already in use, this can happen if the local
// list of ENIs is oudated. Retry the attachment to avoid
Expand Down
13 changes: 8 additions & 5 deletions pkg/ipam/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ type Limits struct {

// IsBareMetal tracks whether an instance is a bare metal instance or not
IsBareMetal bool

// VCpus is the number of virtual CPUs for the instance type
VCpus int

// SupportsFlexibleEnaQueues indicates if the instance type supports flexible ENA queue configuration
SupportsFlexibleEnaQueues bool
}

// AllocationIP is an IP which is available for allocation, or already
Expand Down Expand Up @@ -370,11 +376,8 @@ func (in *Subnet) DeepEqual(other *Subnet) bool {
if in.AvailableIPv6Addresses != other.AvailableIPv6Addresses {
return false
}
if ((in.Tags != nil) && (other.Tags != nil)) || ((in.Tags == nil) != (other.Tags == nil)) {
in, other := &in.Tags, &other.Tags
if !in.DeepEqual(other) {
return false
}
if !in.Tags.DeepEqual(&other.Tags) {
return false
}

return true
Expand Down
Loading