@@ -29,6 +29,7 @@ import (
2929 "github.com/cilium/cilium/pkg/lock"
3030 "github.com/cilium/cilium/pkg/logging"
3131 "github.com/cilium/cilium/pkg/logging/logfields"
32+ cslices "github.com/cilium/cilium/pkg/slices"
3233 "github.com/cilium/cilium/pkg/time"
3334 "github.com/cilium/cilium/pkg/trigger"
3435)
@@ -152,14 +153,14 @@ type ipAllocAttrs struct {
152153 // Excess IP address from a cilium node would be marked for release only after a delay
153154 // configured by excess-ip-release-delay flag. ipsMarkedForRelease tracks the IP and the
154155 // timestamp at which it was marked for release.
155- ipsMarkedForRelease map [string ]time.Time
156+ ipsMarkedForRelease map [netip. Addr ]time.Time
156157
157158 // ipReleaseStatus tracks the state for every IP address considered for release.
158159 // IPAMMarkForRelease : Marked for Release
159160 // IPAMReadyForRelease : Acknowledged as safe to release by agent
160161 // IPAMDoNotRelease : Release request denied by agent
161162 // IPAMReleased : IP released by the operator
162- ipReleaseStatus map [string ]string
163+ ipReleaseStatus map [netip. Addr ]string
163164}
164165
165166// Statistics represent the IP allocation statistics of a node
@@ -611,11 +612,15 @@ func (n *Node) buildPoolAllocated(node *v2.CiliumNode) []ipamTypes.IPAMPoolAlloc
611612 // Here we need to apply a reverse logic to only advertise as /32 CIDRs in the pool
612613 // regular secondary addresses (or the ENI primary IP when using UsePrimaryAddress)
613614 // and not addresses that are already being advertised through a /28 CIDR.
614- for _ , addr := range eni .Addresses {
615- if addressCoveredByPrefix (addr , prefixes ) {
615+ for _ , addrStr := range eni .Addresses {
616+ parsed , err := netip .ParseAddr (addrStr )
617+ if err != nil {
618+ continue
619+ }
620+ if addressCoveredByPrefix (parsed , prefixes ) {
616621 continue
617622 }
618- cidrs = append (cidrs , ipamTypes .IPAMCIDR (addr + "/32" ))
623+ cidrs = append (cidrs , ipamTypes .IPAMCIDR (addrStr + "/32" ))
619624 }
620625 }
621626
@@ -631,18 +636,11 @@ func (n *Node) buildPoolAllocated(node *v2.CiliumNode) []ipamTypes.IPAMPoolAlloc
631636 }
632637}
633638
634- // addressCoveredByPrefix returns true if the given IP address string falls
639+ // addressCoveredByPrefix returns true if the given IP address falls
635640// within any of the provided prefixes.
636- func addressCoveredByPrefix (addr string , prefixes []netip.Prefix ) bool {
637- if len (prefixes ) == 0 {
638- return false
639- }
640- ip , err := netip .ParseAddr (addr )
641- if err != nil {
642- return false
643- }
641+ func addressCoveredByPrefix (addr netip.Addr , prefixes []netip.Prefix ) bool {
644642 for _ , p := range prefixes {
645- if p .Contains (ip ) {
643+ if p .Contains (addr ) {
646644 return true
647645 }
648646 }
@@ -854,12 +852,12 @@ func (n *Node) determineMaintenanceAction() (*maintenanceAction, error) {
854852func (n * Node ) removeStaleReleaseIPs () {
855853 n .mutex .Lock ()
856854 defer n .mutex .Unlock ()
857- for ip , status := range n .ipv4Alloc .ipReleaseStatus {
855+ for addr , status := range n .ipv4Alloc .ipReleaseStatus {
858856 if status != ipamOption .IPAMReleased {
859857 continue
860858 }
861- if _ , ok := n .resource .Status .IPAM .ReleaseIPs [ip ]; ! ok {
862- delete (n .ipv4Alloc .ipReleaseStatus , ip )
859+ if _ , ok := n .resource .Status .IPAM .ReleaseIPs [addr . String () ]; ! ok {
860+ delete (n .ipv4Alloc .ipReleaseStatus , addr )
863861 }
864862 }
865863}
@@ -876,33 +874,37 @@ func (n *Node) abortNoLongerExcessIPs(excessMap map[string]bool) {
876874 if excessMap [ip ] {
877875 continue
878876 }
877+ addr , err := netip .ParseAddr (ip )
878+ if err != nil {
879+ continue
880+ }
879881 // Handshake can be aborted from every state except 'released'
880882 // 'released' state is removed by the agent once the IP has been removed from ciliumnode's IPAM pool as well.
881883 // But if the IP is back in the pool, we need to remove it from the release status map.
882884 if status == ipamOption .IPAMReleased {
883885 // Check if the IP is back in the pool despite being marked as released
884886 if _ , ok := n .resource .Spec .IPAM .Pool [ip ]; ok {
885887 delete (n .resource .Status .IPAM .ReleaseIPs , ip )
886- delete (n .ipv4Alloc .ipsMarkedForRelease , ip )
887- delete (n .ipv4Alloc .ipReleaseStatus , ip )
888+ delete (n .ipv4Alloc .ipsMarkedForRelease , addr )
889+ delete (n .ipv4Alloc .ipReleaseStatus , addr )
888890 }
889891
890892 // If it's still released and not in the pool, we don't need to do anything
891893 continue
892894 }
893895
894- if status , ok := n .ipv4Alloc .ipReleaseStatus [ip ]; ok && status != ipamOption .IPAMReleased {
895- delete (n .ipv4Alloc .ipsMarkedForRelease , ip )
896- delete (n .ipv4Alloc .ipReleaseStatus , ip )
896+ if status , ok := n .ipv4Alloc .ipReleaseStatus [addr ]; ok && status != ipamOption .IPAMReleased {
897+ delete (n .ipv4Alloc .ipsMarkedForRelease , addr )
898+ delete (n .ipv4Alloc .ipReleaseStatus , addr )
897899 }
898900 }
899901}
900902
901903// handleIPReleaseResponse handles IPs agent has already responded to
902904// caller must hold mutex lock
903- func (n * Node ) handleIPReleaseResponse (markedIP string , ipsToRelease * []string ) bool {
905+ func (n * Node ) handleIPReleaseResponse (markedIP netip. Addr , ipsToRelease * []netip. Addr ) bool {
904906 if n .resource .Status .IPAM .ReleaseIPs != nil {
905- if status , ok := n .resource .Status .IPAM .ReleaseIPs [markedIP ]; ok {
907+ if status , ok := n .resource .Status .IPAM .ReleaseIPs [markedIP . String () ]; ok {
906908 switch status {
907909 case ipamOption .IPAMReadyForRelease :
908910 * ipsToRelease = append (* ipsToRelease , markedIP )
@@ -932,29 +934,33 @@ func (n *Node) handleIPReleaseResponse(markedIP string, ipsToRelease *[]string)
932934//
933935// Handshake would be aborted if there are new allocations and the node doesn't have IPs in excess anymore.
934936func (n * Node ) handleIPRelease (ctx context.Context , a * maintenanceAction ) (instanceMutated bool , err error ) {
935- var ipsToMark []string
936- var ipsToRelease []string
937+ var ipsToMark []netip. Addr
938+ var ipsToRelease []netip. Addr
937939
938940 n .mutex .Lock ()
939941
940942 // Update timestamps for IPs from this iteration
941943 releaseTS := time .Now ()
942944 if a .release != nil && a .release .IPsToRelease != nil {
943945 for _ , ip := range a .release .IPsToRelease {
944- if _ , ok := n .ipv4Alloc .ipsMarkedForRelease [ip ]; ! ok {
945- n .ipv4Alloc .ipsMarkedForRelease [ip ] = releaseTS
946+ addr , err := netip .ParseAddr (ip )
947+ if err != nil {
948+ continue
949+ }
950+ if _ , ok := n .ipv4Alloc .ipsMarkedForRelease [addr ]; ! ok {
951+ n .ipv4Alloc .ipsMarkedForRelease [addr ] = releaseTS
946952 }
947953 }
948954 }
949955
950956 if n .ipv4Alloc .ipsMarkedForRelease == nil || a .release == nil || len (a .release .IPsToRelease ) == 0 {
951957 // Resetting ipsMarkedForRelease if there are no IPs to release in this iteration
952- n .ipv4Alloc .ipsMarkedForRelease = make (map [string ]time.Time )
958+ n .ipv4Alloc .ipsMarkedForRelease = make (map [netip. Addr ]time.Time )
953959 }
954960
955961 for markedIP , ts := range n .ipv4Alloc .ipsMarkedForRelease {
956962 // Determine which IPs are still marked for release.
957- stillMarkedForRelease := slices .Contains (a .release .IPsToRelease , markedIP )
963+ stillMarkedForRelease := slices .Contains (a .release .IPsToRelease , markedIP . String () )
958964 if ! stillMarkedForRelease {
959965 // n.determineMaintenanceAction() only returns the IPs on the interface with maximum number of IPs that
960966 // can be freed up. If the selected interface changes or if this IP is not excess anymore, remove entry
@@ -975,12 +981,12 @@ func (n *Node) handleIPRelease(ctx context.Context, a *maintenanceAction) (insta
975981 ipsToMark = append (ipsToMark , markedIP )
976982 }
977983
978- for _ , ip := range ipsToMark {
984+ for _ , addr := range ipsToMark {
979985 n .logger .Load ().Debug (
980986 "Marking IP for release" ,
981- logfields .IPAddr , ip ,
987+ logfields .IPAddr , addr ,
982988 )
983- n .ipv4Alloc .ipReleaseStatus [ip ] = ipamOption .IPAMMarkForRelease
989+ n .ipv4Alloc .ipReleaseStatus [addr ] = ipamOption .IPAMMarkForRelease
984990 }
985991 n .mutex .Unlock ()
986992
@@ -995,7 +1001,7 @@ func (n *Node) handleIPRelease(ctx context.Context, a *maintenanceAction) (insta
9951001 n .abortNoLongerExcessIPs (excessMap )
9961002
9971003 if len (ipsToRelease ) > 0 {
998- a .release .IPsToRelease = ipsToRelease
1004+ a .release .IPsToRelease = cslices . Map ( ipsToRelease , netip . Addr . String )
9991005
10001006 nodeStats := n .Stats ()
10011007
@@ -1031,9 +1037,9 @@ func (n *Node) handleIPRelease(ctx context.Context, a *maintenanceAction) (insta
10311037 n .manager .metricsAPI .AddIPRelease (string (a .release .PoolID ), int64 (len (a .release .IPsToRelease )))
10321038 // Remove the IPs from ipsMarkedForRelease
10331039 n .mutex .Lock ()
1034- for _ , ip := range ipsToRelease {
1035- delete (n .ipv4Alloc .ipsMarkedForRelease , ip )
1036- n .ipv4Alloc .ipReleaseStatus [ip ] = ipamOption .IPAMReleased
1040+ for _ , addr := range ipsToRelease {
1041+ delete (n .ipv4Alloc .ipsMarkedForRelease , addr )
1042+ n .ipv4Alloc .ipReleaseStatus [addr ] = ipamOption .IPAMReleased
10371043 }
10381044 n .mutex .Unlock ()
10391045 return true , nil
@@ -1188,7 +1194,8 @@ func (n *Node) PopulateIPReleaseStatus(node *v2.CiliumNode) {
11881194 n .mutex .Lock ()
11891195 defer n .mutex .Unlock ()
11901196 releaseStatus := make (map [string ]ipamTypes.IPReleaseStatus )
1191- for ip , status := range n .ipv4Alloc .ipReleaseStatus {
1197+ for addr , status := range n .ipv4Alloc .ipReleaseStatus {
1198+ ip := addr .String ()
11921199 if existingStatus , ok := node .Status .IPAM .ReleaseIPs [ip ]; ok && status == ipamOption .IPAMMarkForRelease {
11931200 // retain status if agent already responded to this IP
11941201 if existingStatus == ipamOption .IPAMReadyForRelease || existingStatus == ipamOption .IPAMDoNotRelease {
0 commit comments