diff --git a/pkg/rings/rings.go b/pkg/rings/rings.go index d14d93c..f75def5 100644 --- a/pkg/rings/rings.go +++ b/pkg/rings/rings.go @@ -19,6 +19,8 @@ const ( // when its a gateway connected to Ring 0 (backbone). NodeZeroMax = (1 << 8) - 1 + // RingZeroBits indicates the size of the prefix on the ring 0 (backbone) network. + RingZeroBits = 16 // RingOneBits indicates the size of the prefix on the ring 1 (lan) network. RingOneBits = 20 ) diff --git a/pkg/rings/zero.go b/pkg/rings/zero.go new file mode 100644 index 0000000..6b79580 --- /dev/null +++ b/pkg/rings/zero.go @@ -0,0 +1,40 @@ +package rings + +import "net/netip" + +// RingZeroPrefix represents the backbone that connects gateways +// of the different Ring 1 networks. +// +// The ring 0 network corresponds to what would be ring 2 for region_id 0. +// 10.0.0.0-10.0.255.255 +func RingZeroPrefix(region RegionID, zone ZoneID) (cidr netip.Prefix, err error) { + switch { + case !region.Valid(): + err = ErrOutOfRange(region, "region") + case !zone.Valid(): + err = ErrOutOfRange(zone, "zone") + default: + addr := AddrFrom4(10, 0, uint(region)<<4+uint(zone), 0) + cidr = netip.PrefixFrom(addr, RingZeroBits) + } + + return cidr, err +} + +// RingZeroAddress returns a Ring 0 address for a particular node. +// +// A ring 0 address looks like 10.0.(region_id << 4 + zone_id).(node_id)/20 +func RingZeroAddress(region RegionID, zone ZoneID, node NodeID) (addr netip.Addr, err error) { + switch { + case !region.Valid(): + err = ErrOutOfRange(region, "region") + case !zone.Valid(): + err = ErrOutOfRange(zone, "zone") + case !node.ValidZero(): + err = ErrOutOfRange(node, "node") + default: + addr = AddrFrom4(10, 0, uint(region)<<4+uint(zone), uint(node)) + } + + return addr, err +}