@@ -6,14 +6,17 @@ package linux
66import (
77 "errors"
88 "fmt"
9+ "iter"
910 "log/slog"
1011 "net"
12+ "net/netip"
1113 "os"
1214
1315 "github.com/vishvananda/netlink"
16+ "go4.org/netipx"
1417 "golang.org/x/sys/unix"
18+ "k8s.io/apimachinery/pkg/util/sets"
1519
16- "github.com/cilium/cilium/pkg/cidr"
1720 "github.com/cilium/cilium/pkg/datapath/linux/ipsec"
1821 "github.com/cilium/cilium/pkg/datapath/linux/ipsec/types"
1922 ipsecTypes "github.com/cilium/cilium/pkg/datapath/linux/ipsec/types"
@@ -132,6 +135,18 @@ func (n *linuxNodeHandler) enableSubnetIPsec(v4CIDR, v6CIDR []*net.IPNet) error
132135 return errs
133136}
134137
138+ // prefixesToIPNets yields the *net.IPNet form of each prefix, the form the
139+ // xfrm and route helpers still consume.
140+ func prefixesToIPNets (prefixes []netip.Prefix ) iter.Seq [* net.IPNet ] {
141+ return func (yield func (* net.IPNet ) bool ) {
142+ for _ , p := range prefixes {
143+ if ! yield (netipx .PrefixIPNet (p )) {
144+ return
145+ }
146+ }
147+ }
148+ }
149+
135150func (n * linuxNodeHandler ) enableIPsec (oldNode , newNode * nodeTypes.Node , nodeID uint16 ) error {
136151 var errs error
137152 if newNode .IsLocal () {
@@ -152,12 +167,12 @@ func (n *linuxNodeHandler) enableIPsec(oldNode, newNode *nodeTypes.Node, nodeID
152167 // the mark fields. This uses XFRM_OUTPUT_MARK added in 4.14 kernels.
153168 zeroMark := option .Config .EnableEndpointRoutes
154169
155- if n .nodeConfig .EnableIPv4 && (newNode .IPv4AllocCIDR != nil || n .subnetEncryption ()) {
170+ if n .nodeConfig .EnableIPv4 && (newNode .IPv4AllocCIDR . IsValid () || n .subnetEncryption ()) {
156171 update , err := n .enableIPsecIPv4 (oldNode , newNode , nodeID , zeroMark , updateExisting )
157172 statesUpdated = statesUpdated && update
158173 errs = errors .Join (errs , err )
159174 }
160- if n .nodeConfig .EnableIPv6 && (newNode .IPv6AllocCIDR != nil || n .subnetEncryption ()) {
175+ if n .nodeConfig .EnableIPv6 && (newNode .IPv6AllocCIDR . IsValid () || n .subnetEncryption ()) {
161176 update , err := n .enableIPsecIPv6 (oldNode , newNode , nodeID , zeroMark , updateExisting )
162177 statesUpdated = statesUpdated && update
163178 errs = errors .Join (errs , err )
@@ -274,18 +289,21 @@ func (n *linuxNodeHandler) enableIPSecIPv4Do(oldNode, newNode *nodeTypes.Node, n
274289 localCiliumInternalIP := n .nodeConfig .CiliumInternalIPv4
275290 localIP := net .IP (localCiliumInternalIP .AsSlice ())
276291
277- var addedCIDRs , removedCIDRs []* cidr. CIDR
292+ var addedCIDRs , removedCIDRs []netip. Prefix
278293 if oldNode != nil {
279- addedCIDRs , removedCIDRs = cidr .DiffCIDRLists (oldNode .GetIPv4AllocCIDRs (), newNode .GetIPv4AllocCIDRs ())
294+ oldSet := sets .New (oldNode .GetIPv4AllocCIDRs ()... )
295+ newSet := sets .New (newNode .GetIPv4AllocCIDRs ()... )
296+ addedCIDRs = newSet .Difference (oldSet ).UnsortedList ()
297+ removedCIDRs = oldSet .Difference (newSet ).UnsortedList ()
280298 } else {
281299 addedCIDRs = newNode .GetIPv4AllocCIDRs ()
282300 }
283- for _ , remoteCIDR := range cidr . CIDRsToIPNets (addedCIDRs ) {
301+ for remoteCIDR := range prefixesToIPNets (addedCIDRs ) {
284302 if err := n .replaceNodeIPSecOutRoute (remoteCIDR ); err != nil {
285303 errs = errors .Join (errs , fmt .Errorf ("failed to replace ipsec OUT (%q): %w" , remoteCIDR .IP , err ))
286304 }
287305 }
288- for _ , remoteCIDR := range cidr . CIDRsToIPNets (removedCIDRs ) {
306+ for remoteCIDR := range prefixesToIPNets (removedCIDRs ) {
289307 if err := n .deleteNodeIPSecOutRoute (remoteCIDR ); err != nil {
290308 errs = errors .Join (errs , fmt .Errorf ("failed to delete ipsec OUT (%q): %w" , remoteCIDR .IP , err ))
291309 }
@@ -304,7 +322,7 @@ func (n *linuxNodeHandler) enableIPSecIPv4Do(oldNode, newNode *nodeTypes.Node, n
304322 // we have to take into account all the CIDRs and not only the added ones here,
305323 // since some other ipsec related parameters beside the remote CIDR might have been changed
306324 // (e.g: RemoteBootID, RemoteNodeID and so on)
307- for _ , remoteCIDR := range cidr . CIDRsToIPNets (newNode .GetIPv4AllocCIDRs ()) {
325+ for remoteCIDR := range prefixesToIPNets (newNode .GetIPv4AllocCIDRs ()) {
308326 params := ipsecTypes .NewParameters (template )
309327 params .Dir = ipsec .IPSecDirOut
310328 params .SourceSubnet = wildcardCIDR
@@ -318,7 +336,7 @@ func (n *linuxNodeHandler) enableIPSecIPv4Do(oldNode, newNode *nodeTypes.Node, n
318336 }
319337 }
320338
321- for _ , remoteCIDR := range cidr . CIDRsToIPNets (removedCIDRs ) {
339+ for remoteCIDR := range prefixesToIPNets (removedCIDRs ) {
322340 if err := n .ipsecAgent .DeleteXfrmPolicyOut (nodeID , remoteCIDR ); err != nil {
323341 nodeIDStr := fmt .Sprintf ("0x%x" , nodeID )
324342 scopedLog := n .log .With (
@@ -400,13 +418,13 @@ func (n *linuxNodeHandler) enableIPSecIPv4Do(oldNode, newNode *nodeTypes.Node, n
400418 return statesUpdated , errs
401419}
402420
403- func (n * linuxNodeHandler ) enableIPSecDoLocalHost (addedCIDRs , removedCIDRs []* cidr. CIDR ) error {
421+ func (n * linuxNodeHandler ) enableIPSecDoLocalHost (addedCIDRs , removedCIDRs []netip. Prefix ) error {
404422 var errs error
405423
406- for _ , localIPNet := range cidr . CIDRsToIPNets (addedCIDRs ) {
424+ for localIPNet := range prefixesToIPNets (addedCIDRs ) {
407425 errors .Join (errs , n .replaceNodeIPSecInRoute (localIPNet ))
408426 }
409- for _ , localIPNet := range cidr . CIDRsToIPNets (removedCIDRs ) {
427+ for localIPNet := range prefixesToIPNets (removedCIDRs ) {
410428 errors .Join (errs , n .deleteNodeIPSecInRoute (localIPNet ))
411429 }
412430
@@ -420,9 +438,12 @@ func (n *linuxNodeHandler) enableIPsecIPv4(oldNode, newNode *nodeTypes.Node, nod
420438 errs = errors .Join (errs , ipsec .IPsecDefaultDropPolicy (false ))
421439 errs = errors .Join (errs , upsertIPsecLog (n .log , errs , "default-drop IPv4" , wildcardCIDR , wildcardCIDR , spi , 0 ))
422440
423- var addedCIDRs , removedCIDRs []* cidr. CIDR
441+ var addedCIDRs , removedCIDRs []netip. Prefix
424442 if oldNode != nil {
425- addedCIDRs , removedCIDRs = cidr .DiffCIDRLists (oldNode .GetIPv4AllocCIDRs (), newNode .GetIPv4AllocCIDRs ())
443+ oldSet := sets .New (oldNode .GetIPv4AllocCIDRs ()... )
444+ newSet := sets .New (newNode .GetIPv4AllocCIDRs ()... )
445+ addedCIDRs = newSet .Difference (oldSet ).UnsortedList ()
446+ removedCIDRs = oldSet .Difference (newSet ).UnsortedList ()
426447 } else {
427448 addedCIDRs = newNode .GetIPv4AllocCIDRs ()
428449 }
@@ -554,18 +575,21 @@ func (n *linuxNodeHandler) enableIPSecIPv6Do(oldNode, newNode *nodeTypes.Node, n
554575 localCiliumInternalIP := n .nodeConfig .CiliumInternalIPv6
555576 localIP := net .IP (localCiliumInternalIP .AsSlice ())
556577
557- var addedCIDRs , removedCIDRs []* cidr. CIDR
578+ var addedCIDRs , removedCIDRs []netip. Prefix
558579 if oldNode != nil {
559- addedCIDRs , removedCIDRs = cidr .DiffCIDRLists (oldNode .GetIPv6AllocCIDRs (), newNode .GetIPv6AllocCIDRs ())
580+ oldSet := sets .New (oldNode .GetIPv6AllocCIDRs ()... )
581+ newSet := sets .New (newNode .GetIPv6AllocCIDRs ()... )
582+ addedCIDRs = newSet .Difference (oldSet ).UnsortedList ()
583+ removedCIDRs = oldSet .Difference (newSet ).UnsortedList ()
560584 } else {
561585 addedCIDRs = newNode .GetIPv6AllocCIDRs ()
562586 }
563- for _ , remoteCIDR := range cidr . CIDRsToIPNets (addedCIDRs ) {
587+ for remoteCIDR := range prefixesToIPNets (addedCIDRs ) {
564588 if err := n .replaceNodeIPSecOutRoute (remoteCIDR ); err != nil {
565589 errs = errors .Join (errs , fmt .Errorf ("failed to replace ipsec OUT (%q): %w" , remoteCIDR .IP , err ))
566590 }
567591 }
568- for _ , remoteCIDR := range cidr . CIDRsToIPNets (removedCIDRs ) {
592+ for remoteCIDR := range prefixesToIPNets (removedCIDRs ) {
569593 if err := n .deleteNodeIPSecOutRoute (remoteCIDR ); err != nil {
570594 errs = errors .Join (errs , fmt .Errorf ("failed to delete ipsec OUT (%q): %w" , remoteCIDR .IP , err ))
571595 }
@@ -584,7 +608,7 @@ func (n *linuxNodeHandler) enableIPSecIPv6Do(oldNode, newNode *nodeTypes.Node, n
584608 // we have to take into account all the CIDRs and not only the added ones here,
585609 // since some other ipsec related parameters beside the remote CIDR might have been changed
586610 // (e.g: RemoteBootID, RemoteNodeID and so on)
587- for _ , remoteCIDR := range cidr . CIDRsToIPNets (newNode .GetIPv6AllocCIDRs ()) {
611+ for remoteCIDR := range prefixesToIPNets (newNode .GetIPv6AllocCIDRs ()) {
588612 params := ipsecTypes .NewParameters (template )
589613 params .Dir = ipsec .IPSecDirOut
590614 params .SourceSubnet = wildcardCIDR6
@@ -598,7 +622,7 @@ func (n *linuxNodeHandler) enableIPSecIPv6Do(oldNode, newNode *nodeTypes.Node, n
598622 }
599623 }
600624
601- for _ , remoteCIDR := range cidr . CIDRsToIPNets (removedCIDRs ) {
625+ for remoteCIDR := range prefixesToIPNets (removedCIDRs ) {
602626 if err := n .ipsecAgent .DeleteXfrmPolicyOut (nodeID , remoteCIDR ); err != nil {
603627 nodeIDStr := fmt .Sprintf ("0x%x" , nodeID )
604628 scopedLog := n .log .With (
@@ -690,9 +714,12 @@ func (n *linuxNodeHandler) enableIPsecIPv6(oldNode, newNode *nodeTypes.Node, nod
690714 errs = errors .Join (errs , ipsec .IPsecDefaultDropPolicy (true ))
691715 errs = errors .Join (errs , upsertIPsecLog (n .log , errs , "default-drop IPv6" , wildcardCIDR , wildcardCIDR , spi , 0 ))
692716
693- var addedCIDRs , removedCIDRs []* cidr. CIDR
717+ var addedCIDRs , removedCIDRs []netip. Prefix
694718 if oldNode != nil {
695- addedCIDRs , removedCIDRs = cidr .DiffCIDRLists (oldNode .GetIPv6AllocCIDRs (), newNode .GetIPv6AllocCIDRs ())
719+ oldSet := sets .New (oldNode .GetIPv6AllocCIDRs ()... )
720+ newSet := sets .New (newNode .GetIPv6AllocCIDRs ()... )
721+ addedCIDRs = newSet .Difference (oldSet ).UnsortedList ()
722+ removedCIDRs = oldSet .Difference (newSet ).UnsortedList ()
696723 } else {
697724 addedCIDRs = newNode .GetIPv6AllocCIDRs ()
698725 }
@@ -875,13 +902,13 @@ func (n *linuxNodeHandler) deleteIPsec(oldNode *nodeTypes.Node) error {
875902 // remote pod CIDR.
876903 if ! n .subnetEncryption () {
877904 if n .nodeConfig .EnableIPv4 {
878- for _ , remoteCIDR := range cidr . CIDRsToIPNets (oldNode .GetIPv4AllocCIDRs ()) {
905+ for remoteCIDR := range prefixesToIPNets (oldNode .GetIPv4AllocCIDRs ()) {
879906 errs = errors .Join (errs , n .deleteNodeIPSecOutRoute (remoteCIDR ))
880907 }
881908 }
882909
883910 if n .nodeConfig .EnableIPv6 {
884- for _ , remoteCIDR := range cidr . CIDRsToIPNets (oldNode .GetIPv6AllocCIDRs ()) {
911+ for remoteCIDR := range prefixesToIPNets (oldNode .GetIPv6AllocCIDRs ()) {
885912 errs = errors .Join (errs , n .deleteNodeIPSecOutRoute (remoteCIDR ))
886913 }
887914 }
0 commit comments