From 5dd0e8d1b6eb5487c0c63c200430818b8de6b12c Mon Sep 17 00:00:00 2001 From: Yury Kulazhenkov Date: Tue, 8 Oct 2024 20:29:15 +0300 Subject: [PATCH] Add support for /32 and /128 allocations for CIDRPool --- README.md | 2 +- api/v1alpha1/cidrpool_test.go | 8 ++++---- api/v1alpha1/cidrpool_validate.go | 10 ++-------- pkg/ipam-node/controllers/cidrpool/cidrpool.go | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 10b7c2f..cb5fc7b 100644 --- a/README.md +++ b/README.md @@ -394,7 +394,7 @@ spec: > __Notes:__ > > * pool name is composed of alphanumeric letters separated by dots(`.`) underscores(`_`) or hyphens(`-`). -> * `perNodeBlockSize` minimum size is 2. +> * `perNodeBlockSize` minimum size is 1. > * `subnet` must be large enough to accommodate at least one `perNodeBlockSize` block of IPs. diff --git a/api/v1alpha1/cidrpool_test.go b/api/v1alpha1/cidrpool_test.go index 7a7284f..0c6d5d0 100644 --- a/api/v1alpha1/cidrpool_test.go +++ b/api/v1alpha1/cidrpool_test.go @@ -185,8 +185,8 @@ var _ = Describe("CIDRPool", func() { }, Entry("empty", "", int32(30), false), Entry("invalid value", "aaaa", int32(30), false), - Entry("/32", "192.168.1.1/32", int32(32), false), - Entry("/128", "2001:db8:3333:4444::0/128", int32(128), false), + Entry("/32", "192.168.1.1/32", int32(32), true), + Entry("/128", "2001:db8:3333:4444::0/128", int32(128), true), Entry("valid ipv4", "192.168.1.0/24", int32(30), true), Entry("valid ipv6", "2001:db8:3333:4444::0/64", int32(120), true), ) @@ -203,8 +203,8 @@ var _ = Describe("CIDRPool", func() { Entry("not set", "192.168.0.0/16", int32(0), false), Entry("negative", "192.168.0.0/16", int32(-10), false), Entry("larger than CIDR", "192.168.0.0/16", int32(8), false), - Entry("smaller than 31 for IPv4 pool", "192.168.0.0/16", int32(32), false), - Entry("smaller than 127 for IPv6 pool", "2001:db8:3333:4444::0/64", int32(128), false), + Entry("32 for IPv4 pool", "192.168.0.0/16", int32(32), true), + Entry("128 for IPv6 pool", "2001:db8:3333:4444::0/64", int32(128), true), Entry("match CIDR prefix size - ipv4", "192.168.0.0/16", int32(16), true), Entry("match CIDR prefix size - ipv6", "2001:db8:3333:4444::0/64", int32(64), true), ) diff --git a/api/v1alpha1/cidrpool_validate.go b/api/v1alpha1/cidrpool_validate.go index aa4a895..87ae6f4 100644 --- a/api/v1alpha1/cidrpool_validate.go +++ b/api/v1alpha1/cidrpool_validate.go @@ -60,12 +60,6 @@ func (r *CIDRPool) validateCIDR() field.ErrorList { return field.ErrorList{field.Invalid(field.NewPath("spec", "cidr"), r.Spec.CIDR, "network prefix has host bits set")} } - setBits, bitsTotal := network.Mask.Size() - if setBits == bitsTotal { - return field.ErrorList{field.Invalid( - field.NewPath("spec", "cidr"), r.Spec.CIDR, "single IP prefixes are not supported")} - } - if r.Spec.GatewayIndex != nil && *r.Spec.GatewayIndex < 0 { return field.ErrorList{field.Invalid( field.NewPath("spec", "gatewayIndex"), r.Spec.GatewayIndex, "must not be negative")} @@ -75,9 +69,9 @@ func (r *CIDRPool) validateCIDR() field.ErrorList { return field.ErrorList{field.Invalid( field.NewPath("spec", "perNodeNetworkPrefix"), r.Spec.PerNodeNetworkPrefix, "must not be negative")} } - + setBits, bitsTotal := network.Mask.Size() if r.Spec.PerNodeNetworkPrefix == 0 || - r.Spec.PerNodeNetworkPrefix >= int32(bitsTotal) || + r.Spec.PerNodeNetworkPrefix > int32(bitsTotal) || r.Spec.PerNodeNetworkPrefix < int32(setBits) { return field.ErrorList{field.Invalid( field.NewPath("spec", "perNodeNetworkPrefix"), diff --git a/pkg/ipam-node/controllers/cidrpool/cidrpool.go b/pkg/ipam-node/controllers/cidrpool/cidrpool.go index cb5c92f..4aa6404 100644 --- a/pkg/ipam-node/controllers/cidrpool/cidrpool.go +++ b/pkg/ipam-node/controllers/cidrpool/cidrpool.go @@ -72,7 +72,7 @@ func (r *CIDRPoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c } _, nodeSubnet, _ := net.ParseCIDR(alloc.Prefix) startIP := ip.NextIP(nodeSubnet.IP) - if ip.IsPointToPointSubnet(nodeSubnet) { + if ip.IsPointToPointSubnet(nodeSubnet) || ip.IsSingleIPSubnet(nodeSubnet) { startIP = nodeSubnet.IP } endIP := ip.LastIP(nodeSubnet)