github.phpd.cn/cilium/cilium@v1.6.12/pkg/ip/ip.go (about)

     1  // Copyright 2017-2019 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ip
    16  
    17  import (
    18  	"bytes"
    19  	"encoding/binary"
    20  	"fmt"
    21  	"math/big"
    22  	"net"
    23  	"sort"
    24  )
    25  
    26  const (
    27  	ipv4BitLen = 8 * net.IPv4len
    28  	ipv6BitLen = 8 * net.IPv6len
    29  )
    30  
    31  // CountIPsInCIDR takes a RFC4632/RFC4291-formatted IPv4/IPv6 CIDR and
    32  // determines how many IP addresses reside within that CIDR.
    33  // Returns 0 if the input CIDR cannot be parsed.
    34  func CountIPsInCIDR(ipnet *net.IPNet) int {
    35  	subnet, size := ipnet.Mask.Size()
    36  	if subnet == size {
    37  		return 1
    38  	}
    39  	return 1<<uint(size-subnet) - 1
    40  }
    41  
    42  var (
    43  	// v4Mappedv6Prefix is the RFC2765 IPv4-mapped address prefix.
    44  	v4Mappedv6Prefix  = []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff}
    45  	ipv4LeadingZeroes = []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
    46  	defaultIPv4       = []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0}
    47  	defaultIPv6       = []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
    48  	upperIPv4         = []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 255, 255, 255, 255}
    49  	upperIPv6         = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
    50  )
    51  
    52  // NetsByMask is used to sort a list of IP networks by the size of their masks.
    53  // Implements sort.Interface.
    54  type NetsByMask []*net.IPNet
    55  
    56  func (s NetsByMask) Swap(i, j int) {
    57  	s[i], s[j] = s[j], s[i]
    58  }
    59  
    60  func (s NetsByMask) Less(i, j int) bool {
    61  	iPrefixSize, _ := s[i].Mask.Size()
    62  	jPrefixSize, _ := s[j].Mask.Size()
    63  	if iPrefixSize == jPrefixSize {
    64  		return bytes.Compare(s[i].IP, s[j].IP) < 0
    65  	}
    66  	return iPrefixSize < jPrefixSize
    67  }
    68  
    69  func (s NetsByMask) Len() int {
    70  	return len(s)
    71  }
    72  
    73  // Assert that NetsByMask implements sort.Interface.
    74  var _ sort.Interface = NetsByMask{}
    75  var _ sort.Interface = NetsByRange{}
    76  
    77  // NetsByRange is used to sort a list of ranges, first by their last IPs, then by
    78  // their first IPs
    79  // Implements sort.Interface.
    80  type NetsByRange []*netWithRange
    81  
    82  func (s NetsByRange) Swap(i, j int) {
    83  	s[i], s[j] = s[j], s[i]
    84  }
    85  
    86  func (s NetsByRange) Less(i, j int) bool {
    87  	// First compare by last IP.
    88  	lastComparison := bytes.Compare(*s[i].Last, *s[j].Last)
    89  	if lastComparison < 0 {
    90  		return true
    91  	} else if lastComparison > 0 {
    92  		return false
    93  	}
    94  
    95  	// Then compare by first IP.
    96  	firstComparison := bytes.Compare(*s[i].First, *s[i].First)
    97  	if firstComparison < 0 {
    98  		return true
    99  	} else if firstComparison > 0 {
   100  		return false
   101  	}
   102  
   103  	// First and last IPs are the same, so thus are equal, and s[i]
   104  	// is not less than s[j].
   105  	return false
   106  }
   107  
   108  func (s NetsByRange) Len() int {
   109  	return len(s)
   110  }
   111  
   112  // RemoveCIDRs removes the specified CIDRs from another set of CIDRs. If a CIDR
   113  // to remove is not contained within the CIDR, the CIDR to remove is ignored. A
   114  // slice of CIDRs is returned which contains the set of CIDRs provided minus
   115  // the set of CIDRs which  were removed. Both input slices may be modified by
   116  // calling this function.
   117  func RemoveCIDRs(allowCIDRs, removeCIDRs []*net.IPNet) ([]*net.IPNet, error) {
   118  
   119  	// Ensure that we iterate through the provided CIDRs in order of largest
   120  	// subnet first.
   121  	sort.Sort(NetsByMask(removeCIDRs))
   122  
   123  PreLoop:
   124  	// Remove CIDRs which are contained within CIDRs that we want to remove;
   125  	// such CIDRs are redundant.
   126  	for j, removeCIDR := range removeCIDRs {
   127  		for i, removeCIDR2 := range removeCIDRs {
   128  			if i == j {
   129  				continue
   130  			}
   131  			if removeCIDR.Contains(removeCIDR2.IP) {
   132  				removeCIDRs = append(removeCIDRs[:i], removeCIDRs[i+1:]...)
   133  				// Re-trigger loop since we have modified the slice we are iterating over.
   134  				goto PreLoop
   135  			}
   136  		}
   137  	}
   138  
   139  	for _, remove := range removeCIDRs {
   140  	Loop:
   141  		for i, allowCIDR := range allowCIDRs {
   142  
   143  			// Don't allow comparison of different address spaces.
   144  			if allowCIDR.IP.To4() != nil && remove.IP.To4() == nil ||
   145  				allowCIDR.IP.To4() == nil && remove.IP.To4() != nil {
   146  				return nil, fmt.Errorf("cannot mix IP addresses of different IP protocol versions")
   147  			}
   148  
   149  			// Only remove CIDR if it is contained in the subnet we are allowing.
   150  			if allowCIDR.Contains(remove.IP.Mask(remove.Mask)) {
   151  				nets, err := removeCIDR(allowCIDR, remove)
   152  				if err != nil {
   153  					return nil, err
   154  				}
   155  
   156  				// Remove CIDR that we have just processed and append new CIDRs
   157  				// that we computed from removing the CIDR to remove.
   158  				allowCIDRs = append(allowCIDRs[:i], allowCIDRs[i+1:]...)
   159  				allowCIDRs = append(allowCIDRs, nets...)
   160  				goto Loop
   161  			} else if remove.Contains(allowCIDR.IP.Mask(allowCIDR.Mask)) {
   162  				// If a CIDR that we want to remove contains a CIDR in the list
   163  				// that is allowed, then we can just remove the CIDR to allow.
   164  				allowCIDRs = append(allowCIDRs[:i], allowCIDRs[i+1:]...)
   165  				goto Loop
   166  			}
   167  		}
   168  	}
   169  
   170  	return allowCIDRs, nil
   171  }
   172  
   173  func getNetworkPrefix(ipNet *net.IPNet) *net.IP {
   174  	var mask net.IP
   175  
   176  	if ipNet.IP.To4() == nil {
   177  		mask = make(net.IP, net.IPv6len)
   178  		for i := 0; i < len(ipNet.Mask); i++ {
   179  			mask[net.IPv6len-i-1] = ipNet.IP[net.IPv6len-i-1] & ^ipNet.Mask[i]
   180  		}
   181  	} else {
   182  		mask = make(net.IP, net.IPv4len)
   183  		for i := 0; i < net.IPv4len; i++ {
   184  			mask[net.IPv4len-i-1] = ipNet.IP[net.IPv6len-i-1] & ^ipNet.Mask[i]
   185  		}
   186  	}
   187  
   188  	return &mask
   189  }
   190  
   191  func removeCIDR(allowCIDR, removeCIDR *net.IPNet) ([]*net.IPNet, error) {
   192  	var allows []*net.IPNet
   193  	var allowIsIpv4, removeIsIpv4 bool
   194  	var allowBitLen int
   195  
   196  	if allowCIDR.IP.To4() != nil {
   197  		allowIsIpv4 = true
   198  		allowBitLen = ipv4BitLen
   199  	} else {
   200  		allowBitLen = ipv6BitLen
   201  	}
   202  
   203  	if removeCIDR.IP.To4() != nil {
   204  		removeIsIpv4 = true
   205  	}
   206  
   207  	if removeIsIpv4 != allowIsIpv4 {
   208  		return nil, fmt.Errorf("cannot mix IP addresses of different IP protocol versions")
   209  	}
   210  
   211  	// Get size of each CIDR mask.
   212  	allowSize, _ := allowCIDR.Mask.Size()
   213  	removeSize, _ := removeCIDR.Mask.Size()
   214  
   215  	if allowSize >= removeSize {
   216  		return nil, fmt.Errorf("allow CIDR prefix must be a superset of " +
   217  			"remove CIDR prefix")
   218  	}
   219  
   220  	allowFirstIPMasked := allowCIDR.IP.Mask(allowCIDR.Mask)
   221  	removeFirstIPMasked := removeCIDR.IP.Mask(removeCIDR.Mask)
   222  
   223  	// Convert to IPv4 in IPv6 addresses if needed.
   224  	if allowIsIpv4 {
   225  		allowFirstIPMasked = append(v4Mappedv6Prefix, allowFirstIPMasked...)
   226  	}
   227  
   228  	if removeIsIpv4 {
   229  		removeFirstIPMasked = append(v4Mappedv6Prefix, removeFirstIPMasked...)
   230  	}
   231  
   232  	allowFirstIP := &allowFirstIPMasked
   233  	removeFirstIP := &removeFirstIPMasked
   234  
   235  	// Create CIDR prefixes with mask size of Y+1, Y+2 ... X where Y is the mask
   236  	// length of the CIDR prefix B from which we are excluding a CIDR prefix A
   237  	// with mask length X.
   238  	for i := (allowBitLen - allowSize - 1); i >= (allowBitLen - removeSize); i-- {
   239  		// The mask for each CIDR prefix is simply the ith bit flipped, and then
   240  		// zero'ing out all subsequent bits (the host identifier part of the
   241  		// prefix).
   242  		newMaskSize := allowBitLen - i
   243  		newIP := (*net.IP)(flipNthBit((*[]byte)(removeFirstIP), uint(i)))
   244  		for k := range *allowFirstIP {
   245  			(*newIP)[k] = (*allowFirstIP)[k] | (*newIP)[k]
   246  		}
   247  
   248  		newMask := net.CIDRMask(newMaskSize, allowBitLen)
   249  		newIPMasked := newIP.Mask(newMask)
   250  
   251  		newIPNet := net.IPNet{IP: newIPMasked, Mask: newMask}
   252  		allows = append(allows, &newIPNet)
   253  	}
   254  
   255  	return allows, nil
   256  }
   257  
   258  func getByteIndexOfBit(bit uint) uint {
   259  	return net.IPv6len - (bit / 8) - 1
   260  }
   261  
   262  func getNthBit(ip *net.IP, bitNum uint) uint8 {
   263  	byteNum := getByteIndexOfBit(bitNum)
   264  	bits := (*ip)[byteNum]
   265  	b := uint8(bits)
   266  	return b >> (bitNum % 8) & 1
   267  }
   268  
   269  func flipNthBit(ip *[]byte, bitNum uint) *[]byte {
   270  	ipCopy := make([]byte, len(*ip))
   271  	copy(ipCopy, *ip)
   272  	byteNum := getByteIndexOfBit(bitNum)
   273  	ipCopy[byteNum] = ipCopy[byteNum] ^ 1<<(bitNum%8)
   274  
   275  	return &ipCopy
   276  }
   277  
   278  func ipNetToRange(ipNet net.IPNet) netWithRange {
   279  	firstIP := make(net.IP, len(ipNet.IP))
   280  	lastIP := make(net.IP, len(ipNet.IP))
   281  
   282  	copy(firstIP, ipNet.IP)
   283  	copy(lastIP, ipNet.IP)
   284  
   285  	firstIP = firstIP.Mask(ipNet.Mask)
   286  	lastIP = lastIP.Mask(ipNet.Mask)
   287  
   288  	if firstIP.To4() != nil {
   289  		firstIP = append(v4Mappedv6Prefix, firstIP...)
   290  		lastIP = append(v4Mappedv6Prefix, lastIP...)
   291  	}
   292  
   293  	lastIPMask := make(net.IPMask, len(ipNet.Mask))
   294  	copy(lastIPMask, ipNet.Mask)
   295  	for i := range lastIPMask {
   296  		lastIPMask[len(lastIPMask)-i-1] = ^lastIPMask[len(lastIPMask)-i-1]
   297  		lastIP[net.IPv6len-i-1] = lastIP[net.IPv6len-i-1] | lastIPMask[len(lastIPMask)-i-1]
   298  	}
   299  
   300  	return netWithRange{First: &firstIP, Last: &lastIP, Network: &ipNet}
   301  }
   302  
   303  func getPreviousIP(ip net.IP) net.IP {
   304  	// Cannot go lower than zero!
   305  	if ip.Equal(net.IP(defaultIPv4)) || ip.Equal(net.IP(defaultIPv6)) {
   306  		return ip
   307  	}
   308  
   309  	previousIP := make(net.IP, len(ip))
   310  	copy(previousIP, ip)
   311  
   312  	var overflow bool
   313  	var lowerByteBound int
   314  	if ip.To4() != nil {
   315  		lowerByteBound = net.IPv6len - net.IPv4len
   316  	} else {
   317  		lowerByteBound = 0
   318  	}
   319  	for i := len(ip) - 1; i >= lowerByteBound; i-- {
   320  		if overflow || i == len(ip)-1 {
   321  			previousIP[i]--
   322  		}
   323  		// Track if we have overflowed and thus need to continue subtracting.
   324  		if ip[i] == 0 && previousIP[i] == 255 {
   325  			overflow = true
   326  		} else {
   327  			overflow = false
   328  		}
   329  	}
   330  	return previousIP
   331  }
   332  
   333  // GetNextIP returns the next IP from the given IP address. If the given IP is
   334  // the last IP of a v4 or v6 range, the same IP is returned.
   335  func GetNextIP(ip net.IP) net.IP {
   336  	if ip.Equal(upperIPv4) || ip.Equal(upperIPv6) {
   337  		return ip
   338  	}
   339  
   340  	nextIP := make(net.IP, len(ip))
   341  	switch len(ip) {
   342  	case net.IPv4len:
   343  		ipU32 := binary.BigEndian.Uint32(ip)
   344  		ipU32++
   345  		binary.BigEndian.PutUint32(nextIP, ipU32)
   346  		return nextIP
   347  	case net.IPv6len:
   348  		ipU64 := binary.BigEndian.Uint64(ip[net.IPv6len/2:])
   349  		ipU64++
   350  		binary.BigEndian.PutUint64(nextIP[net.IPv6len/2:], ipU64)
   351  		if ipU64 == 0 {
   352  			ipU64 = binary.BigEndian.Uint64(ip[:net.IPv6len/2])
   353  			ipU64++
   354  			binary.BigEndian.PutUint64(nextIP[:net.IPv6len/2], ipU64)
   355  		} else {
   356  			copy(nextIP[:net.IPv6len/2], ip[:net.IPv6len/2])
   357  		}
   358  		return nextIP
   359  	default:
   360  		return ip
   361  	}
   362  }
   363  
   364  func createSpanningCIDR(r netWithRange) net.IPNet {
   365  	// Don't want to modify the values of the provided range, so make copies.
   366  	lowest := *r.First
   367  	highest := *r.Last
   368  
   369  	var isIPv4 bool
   370  	var spanningMaskSize, bitLen, byteLen int
   371  	if lowest.To4() != nil {
   372  		isIPv4 = true
   373  		bitLen = ipv4BitLen
   374  		byteLen = net.IPv4len
   375  	} else {
   376  		bitLen = ipv6BitLen
   377  		byteLen = net.IPv6len
   378  	}
   379  
   380  	if isIPv4 {
   381  		spanningMaskSize = ipv4BitLen
   382  	} else {
   383  		spanningMaskSize = ipv6BitLen
   384  	}
   385  
   386  	// Convert to big Int so we can easily do bitshifting on the IP addresses,
   387  	// since golang only provides up to 64-bit unsigned integers.
   388  	lowestBig := big.NewInt(0).SetBytes(lowest)
   389  	highestBig := big.NewInt(0).SetBytes(highest)
   390  
   391  	// Starting from largest mask / smallest range possible, apply a mask one bit
   392  	// larger in each iteration to the upper bound in the range  until we have
   393  	// masked enough to pass the lower bound in the range. This
   394  	// gives us the size of the prefix for the spanning CIDR to return as
   395  	// well as the IP for the CIDR prefix of the spanning CIDR.
   396  	for spanningMaskSize > 0 && lowestBig.Cmp(highestBig) < 0 {
   397  		spanningMaskSize--
   398  		mask := big.NewInt(1)
   399  		mask = mask.Lsh(mask, uint(bitLen-spanningMaskSize))
   400  		mask = mask.Mul(mask, big.NewInt(-1))
   401  		highestBig = highestBig.And(highestBig, mask)
   402  	}
   403  
   404  	// If ipv4, need to append 0s because math.Big gets rid of preceding zeroes.
   405  	if isIPv4 {
   406  		highest = append(ipv4LeadingZeroes, highestBig.Bytes()...)
   407  	} else {
   408  		highest = highestBig.Bytes()
   409  	}
   410  
   411  	// Int does not store leading zeroes.
   412  	if len(highest) == 0 {
   413  		highest = make([]byte, byteLen)
   414  	}
   415  
   416  	newNet := net.IPNet{IP: highest, Mask: net.CIDRMask(spanningMaskSize, bitLen)}
   417  	return newNet
   418  }
   419  
   420  type netWithRange struct {
   421  	First   *net.IP
   422  	Last    *net.IP
   423  	Network *net.IPNet
   424  }
   425  
   426  func mergeAdjacentCIDRs(ranges []*netWithRange) []*netWithRange {
   427  	// Sort the ranges. This sorts first by the last IP, then first IP, then by
   428  	// the IP network in the list itself
   429  	sort.Sort(NetsByRange(ranges))
   430  
   431  	// Merge adjacent CIDRs if possible.
   432  	for i := len(ranges) - 1; i > 0; i-- {
   433  		first1 := getPreviousIP(*ranges[i].First)
   434  
   435  		// Since the networks are sorted, we know that if a network in the list
   436  		// is adjacent to another one in the list, it will be the network next
   437  		// to it in the list. If the previous IP of the current network we are
   438  		// processing overlaps with the last IP of the previous network in the
   439  		// list, then we can merge the two ranges together.
   440  		if bytes.Compare(first1, *ranges[i-1].Last) <= 0 {
   441  			// Pick the minimum of the first two IPs to represent the start
   442  			// of the new range.
   443  			var minFirstIP *net.IP
   444  			if bytes.Compare(*ranges[i-1].First, *ranges[i].First) < 0 {
   445  				minFirstIP = ranges[i-1].First
   446  			} else {
   447  				minFirstIP = ranges[i].First
   448  			}
   449  
   450  			// Always take the last IP of the ith IP.
   451  			newRangeLast := make(net.IP, len(*ranges[i].Last))
   452  			copy(newRangeLast, *ranges[i].Last)
   453  
   454  			newRangeFirst := make(net.IP, len(*minFirstIP))
   455  			copy(newRangeFirst, *minFirstIP)
   456  
   457  			// Can't set the network field because since we are combining a
   458  			// range of IPs, and we don't yet know what CIDR prefix(es) represent
   459  			// the new range.
   460  			ranges[i-1] = &netWithRange{First: &newRangeFirst, Last: &newRangeLast, Network: nil}
   461  
   462  			// Since we have combined ranges[i] with the preceding item in the
   463  			// ranges list, we can delete ranges[i] from the slice.
   464  			ranges = append(ranges[:i], ranges[i+1:]...)
   465  		}
   466  	}
   467  	return ranges
   468  }
   469  
   470  // coalesceRanges converts ranges into an equivalent list of net.IPNets.
   471  // All IPs in ranges should be of the same address family (IPv4 or IPv6).
   472  func coalesceRanges(ranges []*netWithRange) []*net.IPNet {
   473  	coalescedCIDRs := []*net.IPNet{}
   474  	// Create CIDRs from ranges that were combined if needed.
   475  	for _, netRange := range ranges {
   476  		// If the Network field of netWithRange wasn't modified, then we can
   477  		// add it to the list which we will return, as it cannot be joined with
   478  		// any other CIDR in the list.
   479  		if netRange.Network != nil {
   480  			coalescedCIDRs = append(coalescedCIDRs, netRange.Network)
   481  		} else {
   482  			// We have joined two ranges together, so we need to find the new CIDRs
   483  			// that represent this range.
   484  			rangeCIDRs := rangeToCIDRs(*netRange.First, *netRange.Last)
   485  			coalescedCIDRs = append(coalescedCIDRs, rangeCIDRs...)
   486  		}
   487  	}
   488  
   489  	return coalescedCIDRs
   490  }
   491  
   492  // CoalesceCIDRs transforms the provided list of CIDRs into the most-minimal
   493  // equivalent set of IPv4 and IPv6 CIDRs.
   494  // It removes CIDRs that are subnets of other CIDRs in the list, and groups
   495  // together CIDRs that have the same mask size into a CIDR of the same mask
   496  // size provided that they share the same number of most significant
   497  // mask-size bits.
   498  //
   499  // Note: this algorithm was ported from the Python library netaddr.
   500  // https://github.com/drkjam/netaddr .
   501  func CoalesceCIDRs(cidrs []*net.IPNet) ([]*net.IPNet, []*net.IPNet) {
   502  
   503  	ranges4 := []*netWithRange{}
   504  	ranges6 := []*netWithRange{}
   505  
   506  	for _, network := range cidrs {
   507  		newNetToRange := ipNetToRange(*network)
   508  		if network.IP.To4() != nil {
   509  			ranges4 = append(ranges4, &newNetToRange)
   510  		} else {
   511  			ranges6 = append(ranges6, &newNetToRange)
   512  		}
   513  	}
   514  
   515  	return coalesceRanges(mergeAdjacentCIDRs(ranges4)), coalesceRanges(mergeAdjacentCIDRs(ranges6))
   516  }
   517  
   518  // rangeToCIDRs converts the range of IPs covered by firstIP and lastIP to
   519  // a list of CIDRs that contains all of the IPs covered by the range.
   520  func rangeToCIDRs(firstIP, lastIP net.IP) []*net.IPNet {
   521  
   522  	// First, create a CIDR that spans both IPs.
   523  	spanningCIDR := createSpanningCIDR(netWithRange{&firstIP, &lastIP, nil})
   524  	spanningRange := ipNetToRange(spanningCIDR)
   525  	firstIPSpanning := spanningRange.First
   526  	lastIPSpanning := spanningRange.Last
   527  
   528  	cidrList := []*net.IPNet{}
   529  
   530  	// If the first IP of the spanning CIDR passes the lower bound (firstIP),
   531  	// we need to split the spanning CIDR and only take the IPs that are
   532  	// greater than the value which we split on, as we do not want the lesser
   533  	// values since they are less than the lower-bound (firstIP).
   534  	if bytes.Compare(*firstIPSpanning, firstIP) < 0 {
   535  		// Split on the previous IP of the first IP so that the right list of IPs
   536  		// of the partition includes the firstIP.
   537  		prevFirstRangeIP := getPreviousIP(firstIP)
   538  		var bitLen int
   539  		if prevFirstRangeIP.To4() != nil {
   540  			bitLen = ipv4BitLen
   541  		} else {
   542  			bitLen = ipv6BitLen
   543  		}
   544  		_, _, right := partitionCIDR(spanningCIDR, net.IPNet{IP: prevFirstRangeIP, Mask: net.CIDRMask(bitLen, bitLen)})
   545  
   546  		// Append all CIDRs but the first, as this CIDR includes the upper
   547  		// bound of the spanning CIDR, which we still need to partition on.
   548  		cidrList = append(cidrList, right...)
   549  		spanningCIDR = *right[0]
   550  		cidrList = cidrList[1:]
   551  	}
   552  
   553  	// Conversely, if the last IP of the spanning CIDR passes the upper bound
   554  	// (lastIP), we need to split the spanning CIDR and only take the IPs that
   555  	// are greater than the value which we split on, as we do not want the greater
   556  	// values since they are greater than the upper-bound (lastIP).
   557  	if bytes.Compare(*lastIPSpanning, lastIP) > 0 {
   558  		// Split on the next IP of the last IP so that the left list of IPs
   559  		// of the partition include the lastIP.
   560  		nextFirstRangeIP := GetNextIP(lastIP)
   561  		var bitLen int
   562  		if nextFirstRangeIP.To4() != nil {
   563  			bitLen = ipv4BitLen
   564  		} else {
   565  			bitLen = ipv6BitLen
   566  		}
   567  		left, _, _ := partitionCIDR(spanningCIDR, net.IPNet{IP: nextFirstRangeIP, Mask: net.CIDRMask(bitLen, bitLen)})
   568  		cidrList = append(cidrList, left...)
   569  	} else {
   570  		// Otherwise, there is no need to partition; just use add the spanning
   571  		// CIDR to the list of networks.
   572  		cidrList = append(cidrList, &spanningCIDR)
   573  	}
   574  	return cidrList
   575  }
   576  
   577  // partitionCIDR returns a list of IP Networks partitioned upon excludeCIDR.
   578  // The first list contains the networks to the left of the excludeCIDR in the
   579  // partition,  the second is a list containing the excludeCIDR itself if it is
   580  // contained within the targetCIDR (nil otherwise), and the
   581  // third is a list containing the networks to the right of the excludeCIDR in
   582  // the partition.
   583  func partitionCIDR(targetCIDR net.IPNet, excludeCIDR net.IPNet) ([]*net.IPNet, []*net.IPNet, []*net.IPNet) {
   584  	var targetIsIPv4 bool
   585  	if targetCIDR.IP.To4() != nil {
   586  		targetIsIPv4 = true
   587  	}
   588  
   589  	targetIPRange := ipNetToRange(targetCIDR)
   590  	excludeIPRange := ipNetToRange(excludeCIDR)
   591  
   592  	targetFirstIP := *targetIPRange.First
   593  	targetLastIP := *targetIPRange.Last
   594  
   595  	excludeFirstIP := *excludeIPRange.First
   596  	excludeLastIP := *excludeIPRange.Last
   597  
   598  	targetMaskSize, _ := targetCIDR.Mask.Size()
   599  	excludeMaskSize, _ := excludeCIDR.Mask.Size()
   600  
   601  	if bytes.Compare(excludeLastIP, targetFirstIP) < 0 {
   602  		return nil, nil, []*net.IPNet{&targetCIDR}
   603  	} else if bytes.Compare(targetLastIP, excludeFirstIP) < 0 {
   604  		return []*net.IPNet{&targetCIDR}, nil, nil
   605  	}
   606  
   607  	if targetMaskSize >= excludeMaskSize {
   608  		return nil, []*net.IPNet{&targetCIDR}, nil
   609  	}
   610  
   611  	left := []*net.IPNet{}
   612  	right := []*net.IPNet{}
   613  
   614  	newPrefixLen := targetMaskSize + 1
   615  
   616  	targetFirstCopy := make(net.IP, len(targetFirstIP))
   617  	copy(targetFirstCopy, targetFirstIP)
   618  
   619  	iLowerOld := make(net.IP, len(targetFirstCopy))
   620  	copy(iLowerOld, targetFirstCopy)
   621  
   622  	// Since golang only supports up to unsigned 64-bit integers, and we need
   623  	// to perform addition on addresses, use math/big library, which allows
   624  	// for manipulation of large integers.
   625  
   626  	// Used to track the current lower and upper bounds of the ranges to compare
   627  	// to excludeCIDR.
   628  	iLower := big.NewInt(0)
   629  	iUpper := big.NewInt(0)
   630  	iLower = iLower.SetBytes(targetFirstCopy)
   631  
   632  	var bitLen int
   633  
   634  	if targetIsIPv4 {
   635  		bitLen = ipv4BitLen
   636  	} else {
   637  		bitLen = ipv6BitLen
   638  	}
   639  	shiftAmount := (uint)(bitLen - newPrefixLen)
   640  
   641  	targetIPInt := big.NewInt(0)
   642  	targetIPInt.SetBytes(targetFirstIP.To16())
   643  
   644  	exp := big.NewInt(0)
   645  
   646  	// Use left shift for exponentiation
   647  	exp = exp.Lsh(big.NewInt(1), shiftAmount)
   648  	iUpper = iUpper.Add(targetIPInt, exp)
   649  
   650  	matched := big.NewInt(0)
   651  
   652  	for excludeMaskSize >= newPrefixLen {
   653  		// Append leading zeros to IPv4 addresses, as math.Big.Int does not
   654  		// append them when the IP address is copied from a byte array to
   655  		// math.Big.Int. Leading zeroes are required for parsing IPv4 addresses
   656  		// for use with net.IP / net.IPNet.
   657  		var iUpperBytes, iLowerBytes []byte
   658  		if targetIsIPv4 {
   659  			iUpperBytes = append(ipv4LeadingZeroes, iUpper.Bytes()...)
   660  			iLowerBytes = append(ipv4LeadingZeroes, iLower.Bytes()...)
   661  		} else {
   662  			iUpperBytesLen := len(iUpper.Bytes())
   663  			// Make sure that the number of bytes in the array matches what net
   664  			// package expects, as big package doesn't append leading zeroes.
   665  			if iUpperBytesLen != net.IPv6len {
   666  				numZeroesToAppend := net.IPv6len - iUpperBytesLen
   667  				zeroBytes := make([]byte, numZeroesToAppend)
   668  				iUpperBytes = append(zeroBytes, iUpper.Bytes()...)
   669  			} else {
   670  				iUpperBytes = iUpper.Bytes()
   671  
   672  			}
   673  
   674  			iLowerBytesLen := len(iLower.Bytes())
   675  			if iLowerBytesLen != net.IPv6len {
   676  				numZeroesToAppend := net.IPv6len - iLowerBytesLen
   677  				zeroBytes := make([]byte, numZeroesToAppend)
   678  				iLowerBytes = append(zeroBytes, iLower.Bytes()...)
   679  			} else {
   680  				iLowerBytes = iLower.Bytes()
   681  
   682  			}
   683  		}
   684  		// If the IP we are excluding over is of a higher value than the current
   685  		// CIDR prefix we are generating, add the CIDR prefix to the set of IPs
   686  		// to the left of the exclude CIDR
   687  		if bytes.Compare(excludeFirstIP, iUpperBytes) >= 0 {
   688  			left = append(left, &net.IPNet{IP: iLowerBytes, Mask: net.CIDRMask(newPrefixLen, bitLen)})
   689  			matched = matched.Set(iUpper)
   690  		} else {
   691  			// Same as above, but opposite.
   692  			right = append(right, &net.IPNet{IP: iUpperBytes, Mask: net.CIDRMask(newPrefixLen, bitLen)})
   693  			matched = matched.Set(iLower)
   694  		}
   695  
   696  		newPrefixLen++
   697  
   698  		if newPrefixLen > bitLen {
   699  			break
   700  		}
   701  
   702  		iLower = iLower.Set(matched)
   703  		iUpper = iUpper.Add(matched, big.NewInt(0).Lsh(big.NewInt(1), uint(bitLen-newPrefixLen)))
   704  
   705  	}
   706  	excludeList := []*net.IPNet{&excludeCIDR}
   707  
   708  	return left, excludeList, right
   709  }
   710  
   711  // KeepUniqueIPs transforms the provided multiset of IPs into a single set,
   712  // lexicographically sorted via a byte-wise comparison of the IP slices (i.e.
   713  // IPv4 addresses show up before IPv6).
   714  // The slice is manipulated in-place destructively.
   715  //
   716  // 1- Sort the slice by comparing the IPs as bytes
   717  // 2- For every unseen unique IP in the sorted slice, move it to the end of
   718  // the return slice.
   719  // Note that the slice is always large enough and, because it is sorted, we
   720  // will not overwrite a valid element with another. To overwrite an element i
   721  // with j, i must have come before j AND we decided it was a duplicate of the
   722  // element at i-1.
   723  func KeepUniqueIPs(ips []net.IP) []net.IP {
   724  	sort.Slice(ips, func(i, j int) bool {
   725  		return bytes.Compare(ips[i], ips[j]) == -1
   726  	})
   727  
   728  	returnIPs := ips[:0] // len==0 but cap==cap(ips)
   729  	for readIdx, ip := range ips {
   730  		if len(returnIPs) == 0 || !returnIPs[len(returnIPs)-1].Equal(ips[readIdx]) {
   731  			returnIPs = append(returnIPs, ip)
   732  		}
   733  	}
   734  
   735  	return returnIPs
   736  }
   737  
   738  var privateIPBlocks []*net.IPNet
   739  
   740  func initPrivatePrefixes() {
   741  	// We only care about global scope prefixes here.
   742  	for _, cidr := range []string{
   743  		"10.0.0.0/8",     // RFC1918
   744  		"172.16.0.0/12",  // RFC1918
   745  		"192.168.0.0/16", // RFC1918
   746  		"fc00::/7",       // IPv6 ULA
   747  	} {
   748  		_, block, _ := net.ParseCIDR(cidr)
   749  		privateIPBlocks = append(privateIPBlocks, block)
   750  	}
   751  }
   752  
   753  var excludedIPs []net.IP
   754  
   755  func init() {
   756  	initPrivatePrefixes()
   757  	initExcludedIPs()
   758  }
   759  
   760  // IsExcluded returns whether a given IP is must be excluded
   761  // due to coming from blacklisted device.
   762  func IsExcluded(excludeList []net.IP, ip net.IP) bool {
   763  	for _, e := range excludeList {
   764  		if e.Equal(ip) {
   765  			return true
   766  		}
   767  	}
   768  	return false
   769  }
   770  
   771  // IsPublicAddr returns whether a given global IP is from
   772  // a public range.
   773  func IsPublicAddr(ip net.IP) bool {
   774  	for _, block := range privateIPBlocks {
   775  		if block.Contains(ip) {
   776  			return false
   777  		}
   778  	}
   779  	return true
   780  }
   781  
   782  // GetExcludedIPs returns a list of IPs from netdevices that Cilium
   783  // needs to exclude to operate
   784  func GetExcludedIPs() []net.IP {
   785  	return excludedIPs
   786  }
   787  
   788  // GetCIDRPrefixesFromIPs returns all of the ips as a slice of *net.IPNet.
   789  func GetCIDRPrefixesFromIPs(ips []net.IP) []*net.IPNet {
   790  	if len(ips) == 0 {
   791  		return nil
   792  	}
   793  	res := make([]*net.IPNet, 0, len(ips))
   794  	for _, ip := range ips {
   795  		res = append(res, IPToPrefix(ip))
   796  	}
   797  	return res
   798  }
   799  
   800  // IPToPrefix returns the corresponding IPNet for the given IP.
   801  func IPToPrefix(ip net.IP) *net.IPNet {
   802  	bits := net.IPv6len * 8
   803  	if ip.To4() != nil {
   804  		ip = ip.To4()
   805  		bits = net.IPv4len * 8
   806  	}
   807  	prefix := &net.IPNet{
   808  		IP:   ip,
   809  		Mask: net.CIDRMask(bits, bits),
   810  	}
   811  	return prefix
   812  }