in pkg/ipamd/ipamd.go [1642:1710]
func (c *IPAMContext) verifyAndAddPrefixesToDatastore(eni string, attachedENIPrefixes []ec2types.Ipv4PrefixSpecification, needEC2Reconcile bool) map[string]bool {
var ec2VerifiedAddresses []ec2types.Ipv4PrefixSpecification
seenIPs := make(map[string]bool)
for _, privateIPv4Cidr := range attachedENIPrefixes {
strPrivateIPv4Cidr := aws.ToString(privateIPv4Cidr.Ipv4Prefix)
log.Debugf("Check in coolddown Found prefix %s", strPrivateIPv4Cidr)
// Check if this Prefix was recently freed
_, ipv4CidrPtr, err := net.ParseCIDR(strPrivateIPv4Cidr)
if err != nil {
log.Debugf("Failed to parse so continuing with next prefix")
continue
}
found, recentlyFreed := c.reconcileCooldownCache.RecentlyFreed(strPrivateIPv4Cidr)
if found {
if recentlyFreed {
log.Debugf("Reconcile skipping IP %s on ENI %s because it was recently unassigned from the ENI.", strPrivateIPv4Cidr, eni)
continue
} else {
if needEC2Reconcile {
// IMDS data might be stale
log.Debugf("This IP was recently freed, but is now out of cooldown. We need to verify with EC2 control plane.")
// Only call EC2 once for this ENI and post GA fix this logic for both prefixes
// and secondary IPs as per "split the loop" comment
if ec2VerifiedAddresses == nil {
var err error
// Call EC2 to verify Prefixes on this ENI
ec2VerifiedAddresses, err = c.awsClient.GetIPv4PrefixesFromEC2(eni)
if err != nil {
log.Errorf("Failed to fetch ENI IP addresses from EC2! %v", err)
// Do not delete this Prefix from the datastore or cooldown until we have confirmed with EC2
seenIPs[strPrivateIPv4Cidr] = true
continue
}
}
// Verify that the Prefix really belongs to this ENI
isReallyAttachedToENI := false
for _, ec2Addr := range ec2VerifiedAddresses {
if strPrivateIPv4Cidr == aws.ToString(ec2Addr.Ipv4Prefix) {
isReallyAttachedToENI = true
log.Debugf("Verified that IP %s is attached to ENI %s", strPrivateIPv4Cidr, eni)
break
}
}
if !isReallyAttachedToENI {
log.Warnf("Skipping IP %s on ENI %s because it does not belong to this ENI!", strPrivateIPv4Cidr, eni)
continue
}
}
// The IP can be removed from the cooldown cache
// TODO: Here we could check if the Prefix is still used by a pod stuck in Terminating state. (Issue #1091)
c.reconcileCooldownCache.Remove(strPrivateIPv4Cidr)
}
}
err = c.dataStore.AddIPv4CidrToStore(eni, *ipv4CidrPtr, true)
if err != nil && err.Error() != datastore.IPAlreadyInStoreError {
log.Errorf("Failed to reconcile Prefix %s on ENI %s", strPrivateIPv4Cidr, eni)
ipamdErrInc("prefixReconcileAdd")
// Continue to check the other Prefixs instead of bailout due to one wrong IP
continue
}
// Mark action
seenIPs[strPrivateIPv4Cidr] = true
prometheusmetrics.ReconcileCnt.With(prometheus.Labels{"fn": "eniDataStorePoolReconcileAdd"}).Inc()
}
return seenIPs
}