package netsplit import ( "net/netip" "go4.org/netipx" ) /* Split splits the network defined in a CIDRSplitter alongside its configuration and performs the subnetting. This strategy attempts to split a network into subnets of a single uniform explicit size. */ func (c *CIDRSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, err error) { var ok bool var base netip.Prefix var sub netip.Prefix var subPtr *netip.Prefix var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder) if c == nil || c.PrefixLength == 0 || c.BaseSplitter == nil || c.network == nil { return } if base, ok = netipx.FromStdIPNet(c.network); !ok { err = ErrBadBoundary return } if !base.IsValid() { err = ErrBadBoundary return } if c.PrefixLength < uint8(base.Bits()) { err = ErrBigPrefix return } ipsb.AddPrefix(base) if remaining, err = ipsb.IPSet(); err != nil { return } for { if sub, remaining, ok = remaining.RemoveFreePrefix(c.PrefixLength); !ok { if !sub.IsValid() { // No error; it's literally impossible since we network on boundaries. // We just hit the end of the prefix. break } } subPtr = new(netip.Prefix) *subPtr = sub nets = append(nets, subPtr) } return }