Skip to content

Commit fd380fd

Browse files
HadrienPattesmagnani96
authored andcommitted
node: Migrate Node alloc-CIDR fields from *cidr.CIDR to netip
This PR migrates `Node.IPv{4,6}AllocCIDR` and `IPv{4,6}SecondaryAllocCIDRs` from `*cidr.CIDR` to the `types.Prefix` wrapper introduced in cilium#46929. The relevant getters/setters see their signature updated accordingly. This migrations removes `netip.Prefix` -> `*cidr.CIDR` at a couple interface/boundary points for places that have already been migrated to netip (k8s node parsing, datapath ipsec, manager and nodediscovery). For others, a new conversion at the boundary is temporarily introduced until those downstream consumers (mainly datapath `LocalNodeConfiguration`) get updated to netip as well in followup PRs. I'm sorry that this PR/commit is fairly large, but it's not really possible to split it into smaller functionnal units. The Node struct and its alloc CIDR fields are a core construct that are consumed in a lot of places. Related: * cilium#46924 * cilium#24246 Signed-off-by: Hadrien Patte <hadrien.patte@datadoghq.com>
1 parent e5dd26b commit fd380fd

33 files changed

Lines changed: 449 additions & 329 deletions

daemon/infraendpoints/infra_ip_allocation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func (r *infraIPAllocator) allocateRouterIPv4(ctx context.Context, family node.A
119119
if routerIP == nil {
120120
return nil, fmt.Errorf("invalid local-router-ip: %s", r.daemonConfig.LocalRouterIPv4)
121121
}
122-
if r.nodeAddressing.IPv4().AllocationCIDR().Contains(routerIP) {
122+
if r.nodeAddressing.IPv4().AllocationCIDR().Contains(iputil.AddrFromIP(routerIP)) {
123123
r.logger.Warn("Specified router IP is within IPv4 podCIDR.")
124124
}
125125
return routerIP, nil
@@ -134,7 +134,7 @@ func (r *infraIPAllocator) allocateRouterIPv6(ctx context.Context, family node.A
134134
if routerIP == nil {
135135
return nil, fmt.Errorf("invalid local-router-ip: %s", r.daemonConfig.LocalRouterIPv6)
136136
}
137-
if r.nodeAddressing.IPv6().AllocationCIDR().Contains(routerIP) {
137+
if r.nodeAddressing.IPv6().AllocationCIDR().Contains(iputil.AddrFromIP(routerIP)) {
138138
r.logger.Warn("Specified router IP is within IPv6 podCIDR.")
139139
}
140140
return routerIP, nil

pkg/datapath/iptables/reconciler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ func toLocalNodeInfo(n node.LocalNode) localNodeInfo {
6868
v4NativeRoutingCIDR, v6NativeRoutingCIDR string
6969
)
7070

71-
if n.IPv4AllocCIDR != nil {
71+
if n.IPv4AllocCIDR.IsValid() {
7272
v4AllocCIDR = n.IPv4AllocCIDR.String()
7373
}
74-
if n.IPv6AllocCIDR != nil {
74+
if n.IPv6AllocCIDR.IsValid() {
7575
v6AllocCIDR = n.IPv6AllocCIDR.String()
7676
}
7777
if n.Local.IPv4NativeRoutingCIDR != nil {

pkg/datapath/iptables/reconciler_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ func TestReconciliationLoop(t *testing.T) {
158158
Type: addressing.NodeCiliumInternalIP,
159159
},
160160
}
161-
n.IPv4AllocCIDR = cidr.MustParseCIDR("5.5.5.0/24")
162-
n.IPv6AllocCIDR = cidr.MustParseCIDR("2001:aaaa::/96")
161+
n.IPv4AllocCIDR = types.PrefixFrom(netip.MustParsePrefix("5.5.5.0/24"))
162+
n.IPv6AllocCIDR = types.PrefixFrom(netip.MustParsePrefix("2001:aaaa::/96"))
163163
})
164164

165165
txn := db.WriteTxn(devices)
@@ -213,8 +213,8 @@ func TestReconciliationLoop(t *testing.T) {
213213
Type: addressing.NodeCiliumInternalIP,
214214
},
215215
}
216-
n.IPv4AllocCIDR = cidr.MustParseCIDR("6.6.6.0/24")
217-
n.IPv6AllocCIDR = cidr.MustParseCIDR("3002:bbbb::/96")
216+
n.IPv4AllocCIDR = types.PrefixFrom(netip.MustParsePrefix("6.6.6.0/24"))
217+
n.IPv6AllocCIDR = types.PrefixFrom(netip.MustParsePrefix("3002:bbbb::/96"))
218218
})
219219
},
220220
expected: desiredState{

pkg/datapath/linux/ipsec.go

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ package linux
66
import (
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+
135150
func (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
}

pkg/datapath/linux/node.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,8 @@ func (n *linuxNodeHandler) nodeUpdate(oldNode, newNode *nodeTypes.Node, firstAdd
516516
errs error
517517

518518
oldAllIP4AllocCidrs, oldAllIP6AllocCidrs []netip.Prefix
519-
newAllIP4AllocCidrs = cidrsToPrefixes(newNode.GetIPv4AllocCIDRs())
520-
newAllIP6AllocCidrs = cidrsToPrefixes(newNode.GetIPv6AllocCIDRs())
519+
newAllIP4AllocCidrs = newNode.GetIPv4AllocCIDRs()
520+
newAllIP6AllocCidrs = newNode.GetIPv6AllocCIDRs()
521521
oldIP4, oldIP6 net.IP
522522
newIP4 = newNode.GetNodeIP(false)
523523
newIP6 = newNode.GetNodeIP(true)
@@ -529,8 +529,8 @@ func (n *linuxNodeHandler) nodeUpdate(oldNode, newNode *nodeTypes.Node, firstAdd
529529
}
530530

531531
if oldNode != nil {
532-
oldAllIP4AllocCidrs = cidrsToPrefixes(oldNode.GetIPv4AllocCIDRs())
533-
oldAllIP6AllocCidrs = cidrsToPrefixes(oldNode.GetIPv6AllocCIDRs())
532+
oldAllIP4AllocCidrs = oldNode.GetIPv4AllocCIDRs()
533+
oldAllIP6AllocCidrs = oldNode.GetIPv6AllocCIDRs()
534534
oldIP4 = oldNode.GetNodeIP(false)
535535
oldIP6 = oldNode.GetNodeIP(true)
536536

@@ -632,8 +632,8 @@ func (n *linuxNodeHandler) nodeDelete(oldNode *nodeTypes.Node) error {
632632
oldIP4 := oldNode.GetNodeIP(false)
633633
oldIP6 := oldNode.GetNodeIP(true)
634634

635-
oldAllIP4AllocCidrs := cidrsToPrefixes(oldNode.GetIPv4AllocCIDRs())
636-
oldAllIP6AllocCidrs := cidrsToPrefixes(oldNode.GetIPv6AllocCIDRs())
635+
oldAllIP4AllocCidrs := oldNode.GetIPv4AllocCIDRs()
636+
oldAllIP6AllocCidrs := oldNode.GetIPv6AllocCIDRs()
637637

638638
var errs error
639639
if n.nodeConfig.EnableAutoDirectRouting && !n.enableEncapsulation(oldNode) {

0 commit comments

Comments
 (0)