Skip to content

Commit 44a19d8

Browse files
committed
Allow custom-sized CIDR for the management subnets
The octavia-operator previously required the user to pass /16 (or /64 for IPv6) CIDRs for the management subnets, now it's more flexible and allows custom sized CIDRs The functional tests now check that the allocation pools are correctly set, based on those CIDRs. JIRA: OSPRH-11711
1 parent f9239cd commit 44a19d8

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

pkg/octavia/network_parameters.go

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -55,33 +55,31 @@ func getConfigFromNAD(
5555
func GetRangeFromCIDR(
5656
cidr netip.Prefix,
5757
) (start netip.Addr, end netip.Addr) {
58-
// For IPv6, a /64 is expected, if the CIDR is aaaa:bbbb:cccc:dddd::/64,
59-
// the range is aaaa:bbbb:cccc:dddd::5 - aaaa:bbbb:cccc:dddd:ffff:ffff:ffff:fffe
60-
// For IPv4, a /16 is expected, if the CIDR is a.b.0.0/16
61-
// the range is a.b.0.5 - a.b.255.254
62-
// IPs from from 1 to 5 are reserved for later user
63-
addr := cidr.Addr()
64-
if addr.Is6() {
65-
addrBytes := addr.As16()
66-
for i := 8; i < 15; i++ {
67-
addrBytes[i] = 0
68-
}
69-
addrBytes[15] = 5
70-
start = netip.AddrFrom16(addrBytes)
71-
for i := 8; i < 15; i++ {
72-
addrBytes[i] = 0xff
73-
}
74-
addrBytes[15] = 0xfe
75-
end = netip.AddrFrom16(addrBytes)
76-
} else {
77-
addrBytes := addr.As4()
78-
addrBytes[2] = 0
79-
addrBytes[3] = 5
80-
start = netip.AddrFrom4(addrBytes)
81-
addrBytes[2] = 0xff
82-
addrBytes[3] = 0xfe
83-
end = netip.AddrFrom4(addrBytes)
58+
// start is the 5th address of the Cidr
59+
start = cidr.Masked().Addr()
60+
for i := 0; i < 5; i++ {
61+
start = start.Next()
62+
}
63+
64+
bits := cidr.Bits()
65+
if start.Is4() {
66+
// Padding for ipv4 addresses in a [16]bytes table
67+
bits += 96
68+
}
69+
// convert it to a [16]bytes table, set the remaining bits to 1
70+
addrBytes := start.As16()
71+
for b := bits; b < 128; b++ {
72+
addrBytes[b/8] |= 1 << uint(7-(b%8))
8473
}
74+
// convert the table to an ip address to get the last IP
75+
// in case of IPv4, the address should be unmapped
76+
last := netip.AddrFrom16(addrBytes)
77+
if start.Is4() {
78+
last = last.Unmap()
79+
}
80+
// end is the 2nd last
81+
end = last.Prev()
82+
8583
return
8684
}
8785

tests/functional/octavia_controller_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ var _ = Describe("Octavia controller", func() {
663663

664664
spec["lbMgmtNetwork"].(map[string]interface{})["availabilityZoneCIDRs"] = map[string]string{
665665
"az1": "172.34.0.0/16",
666-
"az2": "172.44.0.0/16",
666+
"az2": "172.44.8.0/21",
667667
}
668668
spec["lbMgmtNetwork"].(map[string]interface{})["createDefaultLbMgmtNetwork"] = false
669669
DeferCleanup(th.DeleteInstance, CreateOctavia(octaviaName, spec))
@@ -763,6 +763,16 @@ var _ = Describe("Octavia controller", func() {
763763
CIDR: nadConfig.IPAM.CIDR.String(),
764764
},
765765
}
766+
expectedAllocationPools := map[string]subnets.AllocationPool{
767+
subnetNameAZ1: {
768+
Start: "172.34.0.5",
769+
End: "172.34.255.254",
770+
},
771+
subnetNameAZ2: {
772+
Start: "172.44.8.5",
773+
End: "172.44.15.254",
774+
},
775+
}
766776

767777
resultSubnets := map[string]subnets.Subnet{}
768778
for _, subnet := range apiFixtures.Neutron.Subnets {
@@ -777,6 +787,10 @@ var _ = Describe("Octavia controller", func() {
777787
Expect(subnet.NetworkID).To(Equal(expectedSubnet.NetworkID))
778788
Expect(subnet.CIDR).To(Equal(expectedSubnet.CIDR))
779789
Expect(subnet.HostRoutes).To(Equal(expectedSubnet.HostRoutes))
790+
if expectedAllocationPool, ok := expectedAllocationPools[name]; ok {
791+
Expect(subnet.AllocationPools[0].Start).To(Equal(expectedAllocationPool.Start))
792+
Expect(subnet.AllocationPools[0].End).To(Equal(expectedAllocationPool.End))
793+
}
780794
}
781795

782796
// Routers

0 commit comments

Comments
 (0)