github.com/cilium/cilium@v1.16.2/pkg/ip/ip_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package ip
     5  
     6  import (
     7  	"math/big"
     8  	"net"
     9  	"net/netip"
    10  	"sort"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  type IPTestSuite struct{}
    17  
    18  func setupIPTestSuite(_ testing.TB) *IPTestSuite {
    19  	return &IPTestSuite{}
    20  }
    21  
    22  func TestCountIPs(t *testing.T) {
    23  	tests := map[string]*big.Int{
    24  		"192.168.0.1/32": big.NewInt(0),
    25  		"192.168.0.1/31": big.NewInt(0).Sub(big.NewInt(1), big.NewInt(1)),
    26  		"192.168.0.1/30": big.NewInt(2),
    27  		"192.168.0.1/24": big.NewInt(254),
    28  		"192.168.0.1/16": big.NewInt(65534),
    29  		"::1/128":        big.NewInt(0),
    30  		"::1/120":        big.NewInt(254),
    31  		"fd02:1::/32":    big.NewInt(0).Sub(big.NewInt(2).Exp(big.NewInt(2), big.NewInt(96), nil), big.NewInt(2)),
    32  	}
    33  	for cidr, nIPs := range tests {
    34  		_, ipnet, err := net.ParseCIDR(cidr)
    35  		require.Nil(t, err)
    36  		count := CountIPsInCIDR(ipnet)
    37  		require.EqualValues(t, nIPs, count)
    38  	}
    39  }
    40  
    41  func TestFirstIP(t *testing.T) {
    42  	// Test IPv4.
    43  	desiredIPv4_1 := net.IP{0xa, 0, 0, 0}
    44  	testNetv4_1 := net.IPNet{IP: net.ParseIP("10.0.0.5"), Mask: net.CIDRMask(8, 32)}
    45  	ipNetv4_1 := getNetworkPrefix(&testNetv4_1)
    46  	for k := range *ipNetv4_1 {
    47  		require.Equal(t, desiredIPv4_1[k], (*ipNetv4_1)[k])
    48  	}
    49  	testNetv4_2 := net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)}
    50  	ipNetv4_2 := getNetworkPrefix(&testNetv4_2)
    51  	for k := range *ipNetv4_2 {
    52  		require.Equal(t, desiredIPv4_1[k], (*ipNetv4_2)[k])
    53  	}
    54  
    55  	// Test IPv6
    56  	desiredIPv6_1, testNetv6_1, _ := net.ParseCIDR("fd44:7089:ff32:712b::/64")
    57  
    58  	ipNetv6_1 := getNetworkPrefix(testNetv6_1)
    59  	for k := range *ipNetv6_1 {
    60  		require.Equal(t, desiredIPv6_1[k], (*ipNetv6_1)[k])
    61  	}
    62  }
    63  
    64  func (s *IPTestSuite) testIPNetsEqual(created, expected []*net.IPNet, t *testing.T) {
    65  	require.Len(t, created, len(expected))
    66  	for index := range created {
    67  		require.Equal(t, expected[index].String(), created[index].String())
    68  		require.Equal(t, expected[index].Mask.String(), created[index].Mask.String())
    69  	}
    70  }
    71  
    72  func (s *IPTestSuite) testIPsEqual(created, expected net.IP, t *testing.T) {
    73  	require.Len(t, created, len(expected))
    74  	for k := range created {
    75  		require.Equal(t, expected[k], created[k])
    76  	}
    77  }
    78  
    79  func createIPNet(address string, maskSize int, bitLen int) *net.IPNet {
    80  	return &net.IPNet{IP: net.ParseIP(address), Mask: net.CIDRMask(maskSize, bitLen)}
    81  }
    82  
    83  func createIPRange(first string, last string) *netWithRange {
    84  	firstIP := net.ParseIP(first)
    85  	lastIP := net.ParseIP(last)
    86  	return &netWithRange{First: &firstIP, Last: &lastIP}
    87  }
    88  
    89  func TestRemoveRedundant(t *testing.T) {
    90  	s := setupIPTestSuite(t)
    91  
    92  	CIDRs := []*net.IPNet{
    93  		createIPNet("10.96.0.0", 12, ipv4BitLen),
    94  		createIPNet("10.112.0.0", 13, ipv4BitLen),
    95  	}
    96  	expectedCIDRs := []*net.IPNet{
    97  		createIPNet("10.96.0.0", 12, ipv4BitLen),
    98  		createIPNet("10.112.0.0", 13, ipv4BitLen),
    99  	}
   100  	nonRedundantCIDRs := removeRedundantCIDRs(CIDRs)
   101  	s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t)
   102  
   103  	CIDRs = []*net.IPNet{
   104  		createIPNet("10.96.0.0", 11, ipv4BitLen),
   105  		createIPNet("10.112.0.0", 12, ipv4BitLen),
   106  	}
   107  	expectedCIDRs = []*net.IPNet{
   108  		createIPNet("10.96.0.0", 11, ipv4BitLen),
   109  	}
   110  	nonRedundantCIDRs = removeRedundantCIDRs(CIDRs)
   111  	s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t)
   112  
   113  	CIDRs = []*net.IPNet{
   114  		createIPNet("10.112.0.0", 12, ipv4BitLen),
   115  		createIPNet("10.96.0.0", 11, ipv4BitLen),
   116  	}
   117  	nonRedundantCIDRs = removeRedundantCIDRs(CIDRs)
   118  	s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t)
   119  
   120  	CIDRs = []*net.IPNet{
   121  		createIPNet("10.120.0.0", 13, ipv4BitLen),
   122  		createIPNet("10.93.0.4", 30, ipv4BitLen),
   123  		createIPNet("10.112.0.0", 12, ipv4BitLen),
   124  		createIPNet("10.62.0.33", 32, ipv4BitLen),
   125  		createIPNet("10.96.0.0", 11, ipv4BitLen),
   126  	}
   127  	expectedCIDRs = []*net.IPNet{
   128  		createIPNet("10.93.0.4", 30, ipv4BitLen),
   129  		createIPNet("10.62.0.33", 32, ipv4BitLen),
   130  		createIPNet("10.96.0.0", 11, ipv4BitLen),
   131  	}
   132  	nonRedundantCIDRs = removeRedundantCIDRs(CIDRs)
   133  	s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t)
   134  
   135  	CIDRs = []*net.IPNet{
   136  		createIPNet("10.120.0.0", 13, ipv4BitLen),
   137  		createIPNet("10.93.0.4", 30, ipv4BitLen),
   138  		createIPNet("10.93.0.4", 30, ipv4BitLen),
   139  		createIPNet("10.112.0.0", 12, ipv4BitLen),
   140  		createIPNet("10.62.0.33", 32, ipv4BitLen),
   141  		createIPNet("10.96.0.0", 11, ipv4BitLen),
   142  	}
   143  	expectedCIDRs = []*net.IPNet{
   144  		createIPNet("10.93.0.4", 30, ipv4BitLen),
   145  		createIPNet("10.62.0.33", 32, ipv4BitLen),
   146  		createIPNet("10.96.0.0", 11, ipv4BitLen),
   147  	}
   148  	nonRedundantCIDRs = removeRedundantCIDRs(CIDRs)
   149  	s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t)
   150  }
   151  
   152  func TestRemoveCIDRs(t *testing.T) {
   153  	s := setupIPTestSuite(t)
   154  
   155  	allowCIDRs := []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)}
   156  	removeCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 12, ipv4BitLen),
   157  		createIPNet("10.112.0.0", 13, ipv4BitLen),
   158  	}
   159  	expectedCIDRs := []*net.IPNet{createIPNet("10.128.0.0", 9, ipv4BitLen),
   160  		createIPNet("10.0.0.0", 10, ipv4BitLen),
   161  		createIPNet("10.64.0.0", 11, ipv4BitLen),
   162  		createIPNet("10.120.0.0", 13, ipv4BitLen)}
   163  	allowedCIDRs := RemoveCIDRs(allowCIDRs, removeCIDRs)
   164  	s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t)
   165  
   166  	// Removing superset removes the allowed CIDR
   167  	allowCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 12, ipv4BitLen)}
   168  	removeCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)}
   169  	expectedCIDRs = []*net.IPNet{}
   170  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   171  	s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t)
   172  
   173  	allowCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)}
   174  	removeCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 12, ipv4BitLen),
   175  		createIPNet("10.112.0.0", 13, ipv4BitLen),
   176  		createIPNet("10.62.0.33", 32, ipv4BitLen),
   177  		createIPNet("10.93.0.4", 30, ipv4BitLen),
   178  		createIPNet("10.63.0.5", 13, ipv4BitLen),
   179  	}
   180  	expectedCIDRs = []*net.IPNet{createIPNet("10.128.0.0", 9, ipv4BitLen),
   181  		createIPNet("10.0.0.0", 11, ipv4BitLen),
   182  		createIPNet("10.32.0.0", 12, ipv4BitLen),
   183  		createIPNet("10.48.0.0", 13, ipv4BitLen),
   184  		createIPNet("10.120.0.0", 13, ipv4BitLen),
   185  		createIPNet("10.64.0.0", 12, ipv4BitLen),
   186  		createIPNet("10.80.0.0", 13, ipv4BitLen),
   187  		createIPNet("10.88.0.0", 14, ipv4BitLen),
   188  		createIPNet("10.94.0.0", 15, ipv4BitLen),
   189  		createIPNet("10.92.0.0", 16, ipv4BitLen),
   190  		createIPNet("10.93.128.0", 17, ipv4BitLen),
   191  		createIPNet("10.93.64.0", 18, ipv4BitLen),
   192  		createIPNet("10.93.32.0", 19, ipv4BitLen),
   193  		createIPNet("10.93.16.0", 20, ipv4BitLen),
   194  		createIPNet("10.93.8.0", 21, ipv4BitLen),
   195  		createIPNet("10.93.4.0", 22, ipv4BitLen),
   196  		createIPNet("10.93.2.0", 23, ipv4BitLen),
   197  		createIPNet("10.93.1.0", 24, ipv4BitLen),
   198  		createIPNet("10.93.0.128", 25, ipv4BitLen),
   199  		createIPNet("10.93.0.64", 26, ipv4BitLen),
   200  		createIPNet("10.93.0.32", 27, ipv4BitLen),
   201  		createIPNet("10.93.0.16", 28, ipv4BitLen),
   202  		createIPNet("10.93.0.8", 29, ipv4BitLen),
   203  		createIPNet("10.93.0.0", 30, ipv4BitLen),
   204  	}
   205  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   206  	s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t)
   207  
   208  	// Cannot remove CIDRs that are of a different address family.
   209  	allowCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)}
   210  	removeCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b::", 66, ipv6BitLen)}
   211  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   212  	s.testIPNetsEqual(allowedCIDRs, allowCIDRs, t)
   213  
   214  	allowCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)}
   215  	removeCIDRs = []*net.IPNet{createIPNet("a000::", 8, ipv6BitLen)}
   216  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   217  	s.testIPNetsEqual(allowedCIDRs, allowCIDRs, t)
   218  
   219  	allowCIDRs = []*net.IPNet{createIPNet("a000::", 8, ipv6BitLen)}
   220  	removeCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)}
   221  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   222  	s.testIPNetsEqual(allowedCIDRs, allowCIDRs, t)
   223  
   224  	//IPv6 tests
   225  	allowCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b:ff00::", 64, ipv6BitLen)}
   226  	removeCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b::", 66, ipv6BitLen)}
   227  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   228  	expectedCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b:8000::", 65, ipv6BitLen),
   229  		createIPNet("fd44:7089:ff32:712b:4000::", 66, ipv6BitLen)}
   230  	s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t)
   231  
   232  }
   233  
   234  func TestRemoveSameCIDR(t *testing.T) {
   235  	allowCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 32, ipv4BitLen)}
   236  
   237  	allowedCIDRs := RemoveCIDRs(allowCIDRs, allowCIDRs)
   238  	require.Len(t, allowedCIDRs, 0)
   239  }
   240  
   241  func TestRemoveCIDRsEdgeCases(t *testing.T) {
   242  	s := setupIPTestSuite(t)
   243  
   244  	// Remote some /32s
   245  	allowCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 30, ipv4BitLen)}
   246  	removeCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 32, ipv4BitLen), createIPNet("10.96.0.1", 32, ipv4BitLen)}
   247  	expectedCIDRs := []*net.IPNet{createIPNet("10.96.0.2", 31, ipv4BitLen)}
   248  	allowedCIDRs := RemoveCIDRs(allowCIDRs, removeCIDRs)
   249  	s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t)
   250  
   251  	// Remove some subnets
   252  	allowCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 22, ipv4BitLen)}
   253  	removeCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 24, ipv4BitLen), createIPNet("10.96.1.0", 24, ipv4BitLen)}
   254  	expectedCIDRs = []*net.IPNet{createIPNet("10.96.2.0", 23, ipv4BitLen)}
   255  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   256  	s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t)
   257  
   258  	// Remove all subnets
   259  	allowCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 23, ipv4BitLen)}
   260  	removeCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 24, ipv4BitLen), createIPNet("10.96.1.0", 24, ipv4BitLen)}
   261  	expectedCIDRs = []*net.IPNet{}
   262  	allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs)
   263  	s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t)
   264  }
   265  
   266  func TestByteFunctions(t *testing.T) {
   267  	//flipNthHighestBit
   268  	testBytes := net.IP{0x0, 0x0, 0x0, 0x0}
   269  	expectedBytes := net.IP{0x0, 0x0, 0x0, 0x80}
   270  	flipNthHighestBit(testBytes, 24)
   271  	for k := range expectedBytes {
   272  		require.Equal(t, testBytes[k], expectedBytes[k])
   273  	}
   274  
   275  	testBytes = net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0}
   276  	expectedBytes = net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0}
   277  	flipNthHighestBit(testBytes, 95)
   278  	for k := range expectedBytes {
   279  		require.Equal(t, testBytes[k], expectedBytes[k])
   280  	}
   281  }
   282  
   283  func TestIPNetToRange(t *testing.T) {
   284  	s := setupIPTestSuite(t)
   285  
   286  	testRange := ipNetToRange(*createIPNet("192.0.128.0", 24, ipv4BitLen))
   287  	var expectedFirst, expectedLast []byte
   288  	expectedFirst = append(expectedFirst, v4Mappedv6Prefix...)
   289  	expectedFirst = append(expectedFirst, []byte{192, 0, 128, 0}...)
   290  	expectedFirstIP := net.IP(expectedFirst)
   291  
   292  	expectedLast = append(expectedLast, v4Mappedv6Prefix...)
   293  	expectedLast = append(expectedLast, []byte{192, 0, 128, 255}...)
   294  	expectedLastIP := net.IP(expectedLast)
   295  	expectedRange := netWithRange{First: &expectedFirstIP, Last: &expectedLastIP}
   296  
   297  	s.checkRangesEqual(&expectedRange, &testRange, t)
   298  
   299  	// Check that all bits are masked correctly.
   300  	testRange = ipNetToRange(*createIPNet("192.0.128.255", 24, ipv4BitLen))
   301  	s.checkRangesEqual(&expectedRange, &testRange, t)
   302  
   303  	testRange = ipNetToRange(*createIPNet("fd44:7089:ff32:712b:ff00::", 64, ipv6BitLen))
   304  	testRange = ipNetToRange(*createIPNet("::ffff:0", 128, ipv6BitLen))
   305  
   306  }
   307  
   308  func (s *IPTestSuite) checkRangesEqual(range1, range2 *netWithRange, t *testing.T) {
   309  	for l := range *range1.First {
   310  		require.Equal(t, (*range2.First)[l], (*range1.First)[l])
   311  	}
   312  	for l := range *range1.Last {
   313  		require.Equal(t, (*range2.Last)[l], (*range1.Last)[l])
   314  	}
   315  }
   316  
   317  func TestNetsByRange(t *testing.T) {
   318  	s := setupIPTestSuite(t)
   319  
   320  	ranges := []*netWithRange{}
   321  
   322  	// Check sorting by last IP first
   323  	cidrs := []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen),
   324  		createIPNet("10.0.0.0", 10, ipv4BitLen),
   325  		createIPNet("10.64.0.0", 11, ipv4BitLen),
   326  		createIPNet("10.112.0.0", 12, ipv4BitLen)}
   327  
   328  	for _, network := range cidrs {
   329  		newNetToRange := ipNetToRange(*network)
   330  		ranges = append(ranges, &newNetToRange)
   331  	}
   332  
   333  	expectedRanges := []*netWithRange{
   334  		createIPRange("10.0.0.0", "10.63.255.255"),
   335  		createIPRange("10.64.0.0", "10.95.255.255"),
   336  		createIPRange("10.112.0.0", "10.127.255.255"),
   337  		createIPRange("10.0.0.0", "10.255.255.255")}
   338  	sort.Sort(NetsByRange(ranges))
   339  	// Ensure that length of ranges isn't modified first.
   340  	require.Equal(t, len(expectedRanges), len(ranges))
   341  	for k := range ranges {
   342  		s.checkRangesEqual(ranges[k], expectedRanges[k], t)
   343  	}
   344  
   345  	ranges = []*netWithRange{createIPRange("10.0.0.0", "10.255.255.255"),
   346  		createIPRange("10.255.255.254", "10.255.255.255")}
   347  	expectedRanges = []*netWithRange{createIPRange("10.0.0.0", "10.255.255.255"),
   348  		createIPRange("10.255.255.254", "10.255.255.255")}
   349  	sort.Sort(NetsByRange(ranges))
   350  	// Ensure that length of ranges isn't modified first.
   351  	require.Equal(t, len(expectedRanges), len(ranges))
   352  	for k := range ranges {
   353  		s.checkRangesEqual(ranges[k], expectedRanges[k], t)
   354  	}
   355  
   356  }
   357  
   358  func TestCoalesceCIDRs(t *testing.T) {
   359  	s := setupIPTestSuite(t)
   360  
   361  	cidrs := []*net.IPNet{createIPNet("192.0.128.0", 24, ipv4BitLen),
   362  		createIPNet("192.0.129.0", 24, ipv4BitLen)}
   363  	expected := []*net.IPNet{createIPNet("192.0.128.0", 23, ipv4BitLen)}
   364  	mergedV4CIDRs, mergedV6CIDRs := CoalesceCIDRs(cidrs)
   365  	require.Equal(t, 0, len(mergedV6CIDRs))
   366  	s.testIPNetsEqual(mergedV4CIDRs, expected, t)
   367  
   368  	cidrs = []*net.IPNet{createIPNet("192.0.129.0", 24, ipv4BitLen),
   369  		createIPNet("192.0.130.0", 24, ipv4BitLen)}
   370  	expected = []*net.IPNet{createIPNet("192.0.129.0", 24, ipv4BitLen),
   371  		createIPNet("192.0.130.0", 24, ipv4BitLen)}
   372  	mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs)
   373  	require.Equal(t, 0, len(mergedV6CIDRs))
   374  	s.testIPNetsEqual(mergedV4CIDRs, expected, t)
   375  
   376  	cidrs = []*net.IPNet{createIPNet("192.0.2.112", 30, ipv4BitLen),
   377  		createIPNet("192.0.2.116", 31, ipv4BitLen),
   378  		createIPNet("192.0.2.118", 31, ipv4BitLen)}
   379  	expected = []*net.IPNet{createIPNet("192.0.2.112", 29, ipv4BitLen)}
   380  	mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs)
   381  	require.Equal(t, 0, len(mergedV6CIDRs))
   382  	s.testIPNetsEqual(mergedV4CIDRs, expected, t)
   383  
   384  	cidrs = []*net.IPNet{createIPNet("192.0.2.112", 30, ipv4BitLen),
   385  		createIPNet("192.0.2.116", 32, ipv4BitLen),
   386  		createIPNet("192.0.2.118", 31, ipv4BitLen)}
   387  	expected = []*net.IPNet{createIPNet("192.0.2.112", 30, ipv4BitLen),
   388  		createIPNet("192.0.2.116", 32, ipv4BitLen),
   389  		createIPNet("192.0.2.118", 31, ipv4BitLen)}
   390  	mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs)
   391  	require.Equal(t, 0, len(mergedV6CIDRs))
   392  	s.testIPNetsEqual(mergedV4CIDRs, expected, t)
   393  
   394  	cidrs = []*net.IPNet{createIPNet("192.0.2.112", 31, ipv4BitLen),
   395  		createIPNet("192.0.2.116", 31, ipv4BitLen),
   396  		createIPNet("192.0.2.118", 31, ipv4BitLen)}
   397  	expected = []*net.IPNet{createIPNet("192.0.2.112", 31, ipv4BitLen),
   398  		createIPNet("192.0.2.116", 30, ipv4BitLen)}
   399  	mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs)
   400  	require.Equal(t, 0, len(mergedV6CIDRs))
   401  	s.testIPNetsEqual(mergedV4CIDRs, expected, t)
   402  
   403  	cidrs = []*net.IPNet{createIPNet("192.0.1.254", 31, ipv4BitLen),
   404  		createIPNet("192.0.2.0", 28, ipv4BitLen),
   405  		createIPNet("192.0.2.16", 28, ipv4BitLen),
   406  		createIPNet("192.0.2.32", 28, ipv4BitLen),
   407  		createIPNet("192.0.2.48", 28, ipv4BitLen),
   408  		createIPNet("192.0.2.64", 28, ipv4BitLen),
   409  		createIPNet("192.0.2.80", 28, ipv4BitLen),
   410  		createIPNet("192.0.2.96", 28, ipv4BitLen),
   411  		createIPNet("192.0.2.112", 28, ipv4BitLen),
   412  		createIPNet("192.0.2.128", 28, ipv4BitLen),
   413  		createIPNet("192.0.2.144", 28, ipv4BitLen),
   414  		createIPNet("192.0.2.160", 28, ipv4BitLen),
   415  		createIPNet("192.0.2.176", 28, ipv4BitLen),
   416  		createIPNet("192.0.2.192", 28, ipv4BitLen),
   417  		createIPNet("192.0.2.208", 28, ipv4BitLen),
   418  		createIPNet("192.0.2.224", 28, ipv4BitLen),
   419  		createIPNet("192.0.2.240", 28, ipv4BitLen),
   420  		createIPNet("192.0.3.0", 28, ipv4BitLen),
   421  	}
   422  
   423  	expected = []*net.IPNet{createIPNet("192.0.1.254", 31, ipv4BitLen),
   424  		createIPNet("192.0.2.0", 24, ipv4BitLen),
   425  		createIPNet("192.0.3.0", 28, ipv4BitLen)}
   426  	mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs)
   427  	require.Equal(t, 0, len(mergedV6CIDRs))
   428  	s.testIPNetsEqual(mergedV4CIDRs, expected, t)
   429  
   430  	cidrs = []*net.IPNet{createIPNet("::", 0, ipv6BitLen),
   431  		createIPNet("fe80::1", 128, ipv6BitLen)}
   432  	expected = []*net.IPNet{createIPNet("::", 0, ipv6BitLen)}
   433  	_, mergedV6CIDRs = CoalesceCIDRs(cidrs)
   434  	s.testIPNetsEqual(mergedV6CIDRs, expected, t)
   435  
   436  	// assert cidr_merge(['::/0', '::192.0.2.0/124', 'ff00::101']) == [IPNetwork('::/0')]
   437  	cidrs = []*net.IPNet{createIPNet("::", 0, ipv6BitLen),
   438  		createIPNet("::192.0.2.0", 124, ipv6BitLen),
   439  		createIPNet("ff00::101", 128, ipv6BitLen)}
   440  	_, mergedV6CIDRs = CoalesceCIDRs(cidrs)
   441  	s.testIPNetsEqual(mergedV6CIDRs, expected, t)
   442  }
   443  
   444  func TestRangeToCIDRs(t *testing.T) {
   445  	// IPv4 worst case.
   446  	ipNets := rangeToCIDRs(net.ParseIP("0.0.0.1"), net.ParseIP("255.255.255.254"))
   447  	expected := []*net.IPNet{createIPNet("0.0.0.1", 32, ipv4BitLen),
   448  		createIPNet("0.0.0.2", 31, ipv4BitLen),
   449  		createIPNet("0.0.0.4", 30, ipv4BitLen),
   450  		createIPNet("0.0.0.8", 29, ipv4BitLen),
   451  		createIPNet("0.0.0.16", 28, ipv4BitLen),
   452  		createIPNet("0.0.0.32", 27, ipv4BitLen),
   453  		createIPNet("0.0.0.64", 26, ipv4BitLen),
   454  		createIPNet("0.0.0.128", 25, ipv4BitLen),
   455  		createIPNet("0.0.1.0", 24, ipv4BitLen),
   456  		createIPNet("0.0.2.0", 23, ipv4BitLen),
   457  		createIPNet("0.0.4.0", 22, ipv4BitLen),
   458  		createIPNet("0.0.8.0", 21, ipv4BitLen),
   459  		createIPNet("0.0.16.0", 20, ipv4BitLen),
   460  		createIPNet("0.0.32.0", 19, ipv4BitLen),
   461  		createIPNet("0.0.64.0", 18, ipv4BitLen),
   462  		createIPNet("0.0.128.0", 17, ipv4BitLen),
   463  		createIPNet("0.1.0.0", 16, ipv4BitLen),
   464  		createIPNet("0.2.0.0", 15, ipv4BitLen),
   465  		createIPNet("0.4.0.0", 14, ipv4BitLen),
   466  		createIPNet("0.8.0.0", 13, ipv4BitLen),
   467  		createIPNet("0.16.0.0", 12, ipv4BitLen),
   468  		createIPNet("0.32.0.0", 11, ipv4BitLen),
   469  		createIPNet("0.64.0.0", 10, ipv4BitLen),
   470  		createIPNet("0.128.0.0", 9, ipv4BitLen),
   471  		createIPNet("1.0.0.0", 8, ipv4BitLen),
   472  		createIPNet("2.0.0.0", 7, ipv4BitLen),
   473  		createIPNet("4.0.0.0", 6, ipv4BitLen),
   474  		createIPNet("8.0.0.0", 5, ipv4BitLen),
   475  		createIPNet("16.0.0.0", 4, ipv4BitLen),
   476  		createIPNet("32.0.0.0", 3, ipv4BitLen),
   477  		createIPNet("64.0.0.0", 2, ipv4BitLen),
   478  		createIPNet("128.0.0.0", 2, ipv4BitLen),
   479  		createIPNet("192.0.0.0", 3, ipv4BitLen),
   480  		createIPNet("224.0.0.0", 4, ipv4BitLen),
   481  		createIPNet("240.0.0.0", 5, ipv4BitLen),
   482  		createIPNet("248.0.0.0", 6, ipv4BitLen),
   483  		createIPNet("252.0.0.0", 7, ipv4BitLen),
   484  		createIPNet("254.0.0.0", 8, ipv4BitLen),
   485  		createIPNet("255.0.0.0", 9, ipv4BitLen),
   486  		createIPNet("255.128.0.0", 10, ipv4BitLen),
   487  		createIPNet("255.192.0.0", 11, ipv4BitLen),
   488  		createIPNet("255.224.0.0", 12, ipv4BitLen),
   489  		createIPNet("255.240.0.0", 13, ipv4BitLen),
   490  		createIPNet("255.248.0.0", 14, ipv4BitLen),
   491  		createIPNet("255.252.0.0", 15, ipv4BitLen),
   492  		createIPNet("255.254.0.0", 16, ipv4BitLen),
   493  		createIPNet("255.255.0.0", 17, ipv4BitLen),
   494  		createIPNet("255.255.128.0", 18, ipv4BitLen),
   495  		createIPNet("255.255.192.0", 19, ipv4BitLen),
   496  		createIPNet("255.255.224.0", 20, ipv4BitLen),
   497  		createIPNet("255.255.240.0", 21, ipv4BitLen),
   498  		createIPNet("255.255.249.0", 22, ipv4BitLen),
   499  		createIPNet("255.255.252.0", 23, ipv4BitLen),
   500  		createIPNet("255.255.254.0", 24, ipv4BitLen),
   501  		createIPNet("255.255.255.0", 25, ipv4BitLen),
   502  		createIPNet("255.255.255.128", 26, ipv4BitLen),
   503  		createIPNet("255.255.255.192", 27, ipv4BitLen),
   504  		createIPNet("255.255.255.224", 28, ipv4BitLen),
   505  		createIPNet("255.255.255.240", 29, ipv4BitLen),
   506  		createIPNet("255.255.255.248", 30, ipv4BitLen),
   507  		createIPNet("255.255.255.252", 31, ipv4BitLen),
   508  		createIPNet("255.255.255.254", 32, ipv4BitLen),
   509  	}
   510  
   511  	// Sort both so we can compare easily
   512  	sort.Sort(NetsByMask(expected))
   513  	sort.Sort(NetsByMask(ipNets))
   514  	require.Equal(t, len(expected), len(ipNets))
   515  }
   516  
   517  func TestPreviousIP(t *testing.T) {
   518  	s := setupIPTestSuite(t)
   519  
   520  	ip := net.ParseIP("10.0.0.0")
   521  	expectedPrev := net.ParseIP("9.255.255.255")
   522  	prevIP := getPreviousIP(ip)
   523  	s.testIPsEqual(prevIP, expectedPrev, t)
   524  
   525  	// Check that underflow does not occur.
   526  	ip = net.ParseIP("0.0.0.0")
   527  	prevIP = getPreviousIP(ip)
   528  	expectedPrev = ip
   529  	s.testIPsEqual(prevIP, expectedPrev, t)
   530  
   531  	ip = net.ParseIP("::")
   532  	prevIP = getPreviousIP(ip)
   533  	expectedPrev = ip
   534  	s.testIPsEqual(prevIP, expectedPrev, t)
   535  
   536  	ip = net.ParseIP("10.0.0.1")
   537  	prevIP = getPreviousIP(ip)
   538  	expectedPrev = net.ParseIP("10.0.0.0")
   539  	s.testIPsEqual(prevIP, expectedPrev, t)
   540  
   541  	ip = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
   542  	expectedPrev = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe")
   543  	prevIP = getPreviousIP(ip)
   544  	s.testIPsEqual(prevIP, expectedPrev, t)
   545  }
   546  
   547  func TestNextIP(t *testing.T) {
   548  	expectedNext := net.ParseIP("10.0.0.0")
   549  	ip := net.ParseIP("9.255.255.255")
   550  	nextIP := GetNextIP(ip)
   551  	require.EqualValues(t, expectedNext, nextIP)
   552  
   553  	// Check that overflow does not occur.
   554  	ip = net.ParseIP("255.255.255.255")
   555  	nextIP = GetNextIP(ip)
   556  	expectedNext = ip
   557  	require.EqualValues(t, expectedNext, nextIP)
   558  
   559  	ip = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
   560  	nextIP = GetNextIP(ip)
   561  	expectedNext = ip
   562  	require.EqualValues(t, expectedNext, nextIP)
   563  
   564  	ip = []byte{0xa, 0, 0, 0}
   565  	nextIP = GetNextIP(ip)
   566  	expectedNext = []byte{0xa, 0, 0, 1}
   567  	require.EqualValues(t, expectedNext, nextIP)
   568  
   569  	ip = []byte{0xff, 0xff, 0xff, 0xff}
   570  	nextIP = GetNextIP(ip)
   571  	expectedNext = []byte{0xff, 0xff, 0xff, 0xff}
   572  	require.EqualValues(t, expectedNext, nextIP)
   573  
   574  	ip = net.ParseIP("10.0.0.0")
   575  	nextIP = GetNextIP(ip)
   576  	expectedNext = net.ParseIP("10.0.0.1")
   577  	require.EqualValues(t, expectedNext, nextIP)
   578  
   579  	ip = net.ParseIP("0:0:0:0:ffff:ffff:ffff:ffff")
   580  	nextIP = GetNextIP(ip)
   581  	expectedNext = net.ParseIP("0:0:0:1:0:0:0:0")
   582  	require.EqualValues(t, expectedNext, nextIP)
   583  
   584  	ip = net.ParseIP("ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff")
   585  	nextIP = GetNextIP(ip)
   586  	expectedNext = net.ParseIP("ffff:ffff:ffff:ffff:0:0:0:0")
   587  	require.EqualValues(t, expectedNext, nextIP)
   588  
   589  	ip = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe")
   590  	nextIP = GetNextIP(ip)
   591  	expectedNext = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
   592  	require.EqualValues(t, expectedNext, nextIP)
   593  }
   594  
   595  func TestCreateSpanningCIDR(t *testing.T) {
   596  	s := setupIPTestSuite(t)
   597  
   598  	netRange := createIPRange("10.0.0.0", "10.255.255.255")
   599  	expectedSpanningCIDR := createIPNet("10.0.0.0", 8, ipv4BitLen)
   600  	spanningCIDR := createSpanningCIDR(*netRange)
   601  	s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t)
   602  
   603  	netRange = createIPRange("10.0.0.0", "10.255.255.254")
   604  	expectedSpanningCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen)
   605  	spanningCIDR = createSpanningCIDR(*netRange)
   606  	s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t)
   607  
   608  	netRange = createIPRange("10.0.0.1", "10.0.0.1")
   609  	expectedSpanningCIDR = createIPNet("10.0.0.1", 32, ipv4BitLen)
   610  	spanningCIDR = createSpanningCIDR(*netRange)
   611  	s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t)
   612  
   613  	netRange = createIPRange("10.0.0.1", "10.0.0.2")
   614  	expectedSpanningCIDR = createIPNet("10.0.0.0", 30, ipv4BitLen)
   615  	spanningCIDR = createSpanningCIDR(*netRange)
   616  	s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t)
   617  
   618  	netRange = createIPRange("9.0.0.0", "10.0.0.0")
   619  	expectedSpanningCIDR = createIPNet("8.0.0.0", 6, ipv4BitLen)
   620  	spanningCIDR = createSpanningCIDR(*netRange)
   621  	s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t)
   622  
   623  	netRange = createIPRange("FD44:7089:FF32:712B:FF00:0000:0000:0000", "FD44:7089:FF32:712B:FFFF:FFFF:FFFF:FFFF")
   624  	expectedSpanningCIDR = createIPNet("fd44:7089:ff32:712b:ff00::", 72, ipv6BitLen)
   625  	spanningCIDR = createSpanningCIDR(*netRange)
   626  	s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t)
   627  
   628  }
   629  
   630  func TestPartitionCIDR(t *testing.T) {
   631  	s := setupIPTestSuite(t)
   632  
   633  	targetCIDR := createIPNet("10.0.0.0", 8, ipv4BitLen)
   634  	excludeCIDR := createIPNet("10.255.255.255", 32, ipv4BitLen)
   635  	left, exclude, right := PartitionCIDR(*targetCIDR, *excludeCIDR)
   636  	// Exclude should just contain exclude CIDR
   637  	s.testIPNetsEqual([]*net.IPNet{excludeCIDR}, exclude, t)
   638  	// Nothing should be in right list.
   639  	require.Equal(t, 0, len(right))
   640  	expectedLeft := []*net.IPNet{createIPNet("10.0.0.0", 9, ipv4BitLen),
   641  		createIPNet("10.128.0.0", 10, ipv4BitLen),
   642  		createIPNet("10.192.0.0", 11, ipv4BitLen),
   643  		createIPNet("10.224.0.0", 12, ipv4BitLen),
   644  		createIPNet("10.240.0.0", 13, ipv4BitLen),
   645  		createIPNet("10.248.0.0", 14, ipv4BitLen),
   646  		createIPNet("10.252.0.0", 15, ipv4BitLen),
   647  		createIPNet("10.254.0.0", 16, ipv4BitLen),
   648  		createIPNet("10.255.0.0", 17, ipv4BitLen),
   649  		createIPNet("10.255.128.0", 18, ipv4BitLen),
   650  		createIPNet("10.255.192.0", 19, ipv4BitLen),
   651  		createIPNet("10.255.224.0", 20, ipv4BitLen),
   652  		createIPNet("10.255.240.0", 21, ipv4BitLen),
   653  		createIPNet("10.255.248.0", 22, ipv4BitLen),
   654  		createIPNet("10.255.252.0", 23, ipv4BitLen),
   655  		createIPNet("10.255.254.0", 24, ipv4BitLen),
   656  		createIPNet("10.255.255.0", 25, ipv4BitLen),
   657  		createIPNet("10.255.255.128", 26, ipv4BitLen),
   658  		createIPNet("10.255.255.192", 27, ipv4BitLen),
   659  		createIPNet("10.255.255.224", 28, ipv4BitLen),
   660  		createIPNet("10.255.255.240", 29, ipv4BitLen),
   661  		createIPNet("10.255.255.248", 30, ipv4BitLen),
   662  		createIPNet("10.255.255.252", 31, ipv4BitLen),
   663  		createIPNet("10.255.255.254", 32, ipv4BitLen),
   664  	}
   665  	s.testIPNetsEqual(expectedLeft, left, t)
   666  
   667  	targetCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen)
   668  	excludeCIDR = createIPNet("10.0.0.0", 32, ipv4BitLen)
   669  	left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR)
   670  	// Exclude should just contain exclude CIDR
   671  	s.testIPNetsEqual([]*net.IPNet{excludeCIDR}, exclude, t)
   672  	// Nothing should be in left list.
   673  	require.Equal(t, 0, len(left))
   674  	expectedRight := []*net.IPNet{createIPNet("10.128.0.0", 9, ipv4BitLen),
   675  		createIPNet("10.64.0.0", 10, ipv4BitLen),
   676  		createIPNet("10.32.0.0", 11, ipv4BitLen),
   677  		createIPNet("10.16.0.0", 12, ipv4BitLen),
   678  		createIPNet("10.8.0.0", 13, ipv4BitLen),
   679  		createIPNet("10.4.0.0", 14, ipv4BitLen),
   680  		createIPNet("10.2.0.0", 15, ipv4BitLen),
   681  		createIPNet("10.1.0.0", 16, ipv4BitLen),
   682  		createIPNet("10.0.128.0", 17, ipv4BitLen),
   683  		createIPNet("10.0.64.0", 18, ipv4BitLen),
   684  		createIPNet("10.0.32.0", 19, ipv4BitLen),
   685  		createIPNet("10.0.16.0", 20, ipv4BitLen),
   686  		createIPNet("10.0.8.0", 21, ipv4BitLen),
   687  		createIPNet("10.0.4.0", 22, ipv4BitLen),
   688  		createIPNet("10.0.2.0", 23, ipv4BitLen),
   689  		createIPNet("10.0.1.0", 24, ipv4BitLen),
   690  		createIPNet("10.0.0.128", 25, ipv4BitLen),
   691  		createIPNet("10.0.0.64", 26, ipv4BitLen),
   692  		createIPNet("10.0.0.32", 27, ipv4BitLen),
   693  		createIPNet("10.0.0.16", 28, ipv4BitLen),
   694  		createIPNet("10.0.0.8", 29, ipv4BitLen),
   695  		createIPNet("10.0.0.4", 30, ipv4BitLen),
   696  		createIPNet("10.0.0.2", 31, ipv4BitLen),
   697  		createIPNet("10.0.0.1", 32, ipv4BitLen),
   698  	}
   699  	s.testIPNetsEqual(expectedRight, right, t)
   700  
   701  	// exclude is not in target CIDR and is to left.
   702  	targetCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen)
   703  	excludeCIDR = createIPNet("9.0.0.255", 32, ipv4BitLen)
   704  	left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR)
   705  	require.Equal(t, 0, len(left))
   706  	require.Equal(t, 0, len(exclude))
   707  	s.testIPNetsEqual([]*net.IPNet{targetCIDR}, right, t)
   708  
   709  	// exclude is not in target CIDR and is to right.
   710  	targetCIDR = createIPNet("10.255.255.254", 32, ipv4BitLen)
   711  	excludeCIDR = createIPNet("10.255.255.255", 32, ipv4BitLen)
   712  	left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR)
   713  	require.Equal(t, 0, len(right))
   714  	require.Equal(t, 0, len(exclude))
   715  	s.testIPNetsEqual([]*net.IPNet{targetCIDR}, left, t)
   716  
   717  	// exclude CIDR larger than target CIDR
   718  	targetCIDR = createIPNet("10.96.0.0", 12, ipv4BitLen)
   719  	excludeCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen)
   720  	left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR)
   721  	require.Equal(t, 0, len(left))
   722  	require.Equal(t, 0, len(right))
   723  	s.testIPNetsEqual([]*net.IPNet{targetCIDR}, exclude, t)
   724  
   725  	targetCIDR = createIPNet("fd44:7089:ff32:712b:ff00::", 64, ipv6BitLen)
   726  	excludeCIDR = createIPNet("fd44:7089:ff32:712b::", 66, ipv6BitLen)
   727  
   728  	_, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR)
   729  
   730  	expectedCIDRs := []*net.IPNet{createIPNet("fd44:7089:ff32:712b:8000::", 65, ipv6BitLen),
   731  		createIPNet("fd44:7089:ff32:712b:4000::", 66, ipv6BitLen)}
   732  	s.testIPNetsEqual(expectedCIDRs, right, t)
   733  	s.testIPNetsEqual([]*net.IPNet{excludeCIDR}, exclude, t)
   734  }
   735  
   736  func TestKeepUniqueAddrs(t *testing.T) {
   737  	for _, tc := range []struct {
   738  		name  string
   739  		addrs []netip.Addr
   740  		want  []netip.Addr
   741  	}{
   742  		{
   743  			name:  "nil slice",
   744  			addrs: nil,
   745  			want:  nil,
   746  		},
   747  		{
   748  			name:  "empty slice",
   749  			addrs: []netip.Addr{},
   750  			want:  []netip.Addr{},
   751  		},
   752  		{
   753  			name:  "one element slice",
   754  			addrs: []netip.Addr{netip.MustParseAddr("1.1.1.1")},
   755  			want:  []netip.Addr{netip.MustParseAddr("1.1.1.1")},
   756  		},
   757  		{
   758  			name: "IPv4 all duplicates",
   759  			addrs: []netip.Addr{
   760  				netip.MustParseAddr("1.1.1.1"),
   761  				netip.MustParseAddr("1.1.1.1"),
   762  				netip.MustParseAddr("1.1.1.1"),
   763  			},
   764  			want: []netip.Addr{
   765  				netip.MustParseAddr("1.1.1.1"),
   766  			},
   767  		},
   768  		{
   769  			name: "IPv4 all unique",
   770  			addrs: []netip.Addr{
   771  				netip.MustParseAddr("1.1.1.1"),
   772  				netip.MustParseAddr("2.2.2.2"),
   773  				netip.MustParseAddr("3.3.3.3"),
   774  			},
   775  			want: []netip.Addr{
   776  				netip.MustParseAddr("1.1.1.1"),
   777  				netip.MustParseAddr("2.2.2.2"),
   778  				netip.MustParseAddr("3.3.3.3"),
   779  			},
   780  		},
   781  		{
   782  			name: "IPv4 mixed",
   783  			addrs: []netip.Addr{
   784  				netip.MustParseAddr("3.3.3.3"),
   785  				netip.MustParseAddr("1.1.1.1"),
   786  				netip.MustParseAddr("2.2.2.2"),
   787  				netip.MustParseAddr("2.2.2.2"),
   788  			},
   789  			want: []netip.Addr{
   790  				netip.MustParseAddr("1.1.1.1"),
   791  				netip.MustParseAddr("2.2.2.2"),
   792  				netip.MustParseAddr("3.3.3.3"),
   793  			},
   794  		},
   795  		{
   796  			name: "IPv6 all duplicates",
   797  			addrs: []netip.Addr{
   798  				netip.MustParseAddr("f00d::1"),
   799  				netip.MustParseAddr("f00d::1"),
   800  				netip.MustParseAddr("f00d::1"),
   801  			},
   802  			want: []netip.Addr{
   803  				netip.MustParseAddr("f00d::1"),
   804  			},
   805  		},
   806  		{
   807  			name: "Mixed IPv4 & IPv6",
   808  			addrs: []netip.Addr{
   809  				netip.MustParseAddr("::1"),
   810  				netip.MustParseAddr("f00d::1"),
   811  				netip.MustParseAddr("1.1.1.1"),
   812  				netip.MustParseAddr("f00d::1"),
   813  			},
   814  			want: []netip.Addr{
   815  				netip.MustParseAddr("1.1.1.1"),
   816  				netip.MustParseAddr("::1"),
   817  				netip.MustParseAddr("f00d::1"),
   818  			},
   819  		},
   820  		{
   821  			name: "With IPv6-in-IPv6",
   822  			addrs: []netip.Addr{
   823  				netip.MustParseAddr("::ffff:0101:0101"),
   824  				netip.MustParseAddr("::ffff:1.1.1.1"),
   825  				netip.MustParseAddr("1.1.1.1"),
   826  			},
   827  			want: []netip.Addr{
   828  				netip.MustParseAddr("1.1.1.1"),
   829  				netip.MustParseAddr("::ffff:1.1.1.1"),
   830  			},
   831  		},
   832  	} {
   833  		t.Run(tc.name, func(t *testing.T) {
   834  			got := KeepUniqueAddrs(tc.addrs)
   835  			if len(tc.want) != len(got) {
   836  				t.Errorf("%s: KeepUniqueAddrs(%q): got %d unique addresses, want %d",
   837  					tc.name, tc.addrs, len(got), len(tc.want))
   838  			}
   839  			for i := range got {
   840  				if tc.want[i] != got[i] {
   841  					t.Errorf("%s: KeepUniqueAddrs(%q): mismatching address at index %d: got %v, want %v",
   842  						tc.name, tc.addrs, i, got[i], tc.want[i])
   843  				}
   844  			}
   845  		})
   846  	}
   847  }
   848  
   849  func TestIPVersion(t *testing.T) {
   850  	type args struct {
   851  		ip net.IP
   852  	}
   853  	tests := []struct {
   854  		name string
   855  		args args
   856  		v4   bool
   857  		v6   bool
   858  	}{
   859  		{
   860  			name: "test-1",
   861  			args: args{
   862  				ip: nil,
   863  			},
   864  			v4: false,
   865  			v6: false,
   866  		},
   867  		{
   868  			name: "test-2",
   869  			args: args{
   870  				ip: net.ParseIP("1.1.1.1"),
   871  			},
   872  			v4: true,
   873  			v6: false,
   874  		},
   875  		{
   876  			name: "test-3",
   877  			args: args{
   878  				ip: net.ParseIP("fd00::1"),
   879  			},
   880  			v4: false,
   881  			v6: true,
   882  		},
   883  	}
   884  	for _, tt := range tests {
   885  		got := IsIPv4(tt.args.ip)
   886  		require.EqualValuesf(t, tt.v4, got, "v4 test Name: %s", tt.name)
   887  
   888  		got = IsIPv6(tt.args.ip)
   889  		require.EqualValuesf(t, tt.v6, got, "v6 test Name: %s", tt.name)
   890  	}
   891  }
   892  
   893  func TestIPListEquals(t *testing.T) {
   894  	ips := []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("fd00::1"), net.ParseIP("8.8.8.8")}
   895  	sorted := []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("8.8.8.8"), net.ParseIP("fd00::1")}
   896  
   897  	require.Equal(t, true, UnsortedIPListsAreEqual(ips, sorted))
   898  }
   899  
   900  func TestGetIPFromListByFamily(t *testing.T) {
   901  	tests := []struct {
   902  		name          string
   903  		ips           []net.IP
   904  		needsV4Family bool
   905  		wants         net.IP
   906  	}{
   907  		{
   908  			name:          "test-1",
   909  			ips:           []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("fd00::1"), net.ParseIP("8.8.8.8")},
   910  			needsV4Family: true,
   911  			wants:         net.ParseIP("1.1.1.1"),
   912  		},
   913  		{
   914  			name:          "test-2",
   915  			ips:           []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("fd00::1"), net.ParseIP("8.8.8.8")},
   916  			needsV4Family: false,
   917  			wants:         net.ParseIP("fd00::1"),
   918  		},
   919  		{
   920  			name:          "test-2",
   921  			ips:           []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("8.8.8.8")},
   922  			needsV4Family: false,
   923  			wants:         nil,
   924  		},
   925  	}
   926  
   927  	for _, tt := range tests {
   928  		got := GetIPFromListByFamily(tt.ips, tt.needsV4Family)
   929  		require.EqualValuesf(t, tt.wants.String(), got.String(), "Test Name: %s", tt.name)
   930  	}
   931  }
   932  
   933  func TestGetIPAtIndex(t *testing.T) {
   934  	type args struct {
   935  		cidr  string
   936  		index int64
   937  		want  net.IP
   938  	}
   939  
   940  	tests := []args{
   941  		{
   942  			cidr:  "10.0.0.0/29",
   943  			index: -1,
   944  			want:  net.ParseIP("10.0.0.7"),
   945  		}, {
   946  			cidr:  "10.0.0.0/29",
   947  			index: 0,
   948  			want:  net.ParseIP("10.0.0.0"),
   949  		}, {
   950  			cidr:  "10.0.0.0/29",
   951  			index: 1,
   952  			want:  net.ParseIP("10.0.0.1"),
   953  		}, {
   954  			cidr:  "10.0.0.16/28",
   955  			index: -3,
   956  			want:  net.ParseIP("10.0.0.29"),
   957  		}, {
   958  			cidr:  "10.0.0.0/29",
   959  			index: -3,
   960  			want:  net.ParseIP("10.0.0.5"),
   961  		}, {
   962  			cidr:  "10.0.0.0/25",
   963  			index: -3,
   964  			want:  net.ParseIP("10.0.0.125"),
   965  		}, {
   966  			cidr:  "10.0.0.128/25",
   967  			index: -3,
   968  			want:  net.ParseIP("10.0.0.253"),
   969  		}, {
   970  			cidr:  "10.0.8.0/21",
   971  			index: -3,
   972  			want:  net.ParseIP("10.0.15.253"),
   973  		}, {
   974  			cidr:  "fd00::/64",
   975  			index: -3,
   976  			want:  net.ParseIP("fd00::ffff:ffff:ffff:fffd"),
   977  		},
   978  	}
   979  	for _, tt := range tests {
   980  		_, ipNet, _ := net.ParseCIDR(tt.cidr)
   981  		if got := GetIPAtIndex(*ipNet, tt.index); !got.Equal(tt.want) {
   982  			t.Errorf("GetIPAtIndex() = %v, want %v", got, tt.want)
   983  		}
   984  	}
   985  }
   986  
   987  func TestAddrFromIP(t *testing.T) {
   988  	type args struct {
   989  		ip       net.IP
   990  		wantAddr netip.Addr
   991  		wantOk   bool
   992  	}
   993  
   994  	tests := []args{
   995  		{
   996  			net.ParseIP("10.0.0.1"),
   997  			netip.MustParseAddr("10.0.0.1"),
   998  			true,
   999  		},
  1000  		{
  1001  			net.ParseIP("a::1"),
  1002  			netip.MustParseAddr("a::1"),
  1003  			true,
  1004  		},
  1005  		{
  1006  			net.ParseIP("::ffff:10.0.0.1"),
  1007  			netip.MustParseAddr("10.0.0.1"),
  1008  			true,
  1009  		},
  1010  	}
  1011  	for _, tt := range tests {
  1012  		addr, ok := AddrFromIP(tt.ip)
  1013  		if ok != tt.wantOk {
  1014  			t.Errorf("AddrFromIP(net.IP(%v)) should success", []byte(tt.ip))
  1015  		}
  1016  
  1017  		if addr != tt.wantAddr {
  1018  			t.Errorf("AddrFromIP(net.IP(%v)) = %v want %v", []byte(tt.ip), addr, tt.wantAddr)
  1019  		}
  1020  	}
  1021  }
  1022  
  1023  func TestMustAddrsFromIPs(t *testing.T) {
  1024  	type args struct {
  1025  		ips   []net.IP
  1026  		addrs []netip.Addr
  1027  	}
  1028  	for _, tt := range []args{
  1029  		{
  1030  			ips:   []net.IP{},
  1031  			addrs: []netip.Addr{},
  1032  		},
  1033  		{
  1034  			ips:   []net.IP{net.ParseIP("1.1.1.1")},
  1035  			addrs: []netip.Addr{netip.MustParseAddr("1.1.1.1")},
  1036  		},
  1037  		{
  1038  			ips:   []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("2.2.2.2"), net.ParseIP("0.0.0.0")},
  1039  			addrs: []netip.Addr{netip.MustParseAddr("1.1.1.1"), netip.MustParseAddr("2.2.2.2"), netip.MustParseAddr("0.0.0.0")},
  1040  		},
  1041  	} {
  1042  		addrs := MustAddrsFromIPs(tt.ips)
  1043  		require.EqualValues(t, tt.addrs, addrs)
  1044  	}
  1045  
  1046  	nilIPs := []net.IP{nil}
  1047  	defer func() {
  1048  		if r := recover(); r == nil {
  1049  			t.Errorf("MustAddrsFromIPs(%v) should panic", nilIPs)
  1050  		}
  1051  	}()
  1052  	_ = MustAddrsFromIPs(nilIPs)
  1053  }
  1054  
  1055  func TestPrefixToIpsValidIPv4(t *testing.T) {
  1056  	prefix := "192.168.1.0/30"
  1057  	expectedIPs := []string{"192.168.1.0", "192.168.1.1", "192.168.1.2", "192.168.1.3"}
  1058  	ips, err := PrefixToIps(prefix, 0)
  1059  	require.Nil(t, err)
  1060  	require.EqualValues(t, expectedIPs, ips)
  1061  }
  1062  
  1063  func TestPrefixToIpsValidLimitedIPv4(t *testing.T) {
  1064  	prefix := "192.168.1.0/28"
  1065  	expectedIPs := []string{"192.168.1.0", "192.168.1.1", "192.168.1.2", "192.168.1.3"}
  1066  	ips, err := PrefixToIps(prefix, 4)
  1067  	require.Nil(t, err)
  1068  	require.EqualValues(t, expectedIPs, ips)
  1069  }
  1070  
  1071  func TestPrefixToIpsValidIPv6(t *testing.T) {
  1072  	prefix := "2001:DB8::/126"
  1073  	expectedIPs := []string{"2001:db8::", "2001:db8::1", "2001:db8::2", "2001:db8::3"}
  1074  	ips, err := PrefixToIps(prefix, 0)
  1075  	require.Nil(t, err)
  1076  	require.EqualValues(t, expectedIPs, ips)
  1077  }
  1078  
  1079  func TestPrefixToIpsValidLimitedIPv6(t *testing.T) {
  1080  	prefix := "2001:DB8::/80"
  1081  	expectedIPs := []string{"2001:db8::", "2001:db8::1", "2001:db8::2", "2001:db8::3"}
  1082  	ips, err := PrefixToIps(prefix, 4)
  1083  	require.Nil(t, err)
  1084  	require.EqualValues(t, expectedIPs, ips)
  1085  }
  1086  
  1087  func TestPrefixToIPsInvalidPrefix(t *testing.T) {
  1088  	prefix := "invalid"
  1089  	ips, err := PrefixToIps(prefix, 0)
  1090  	require.Error(t, err)
  1091  	require.Len(t, ips, 0)
  1092  }
  1093  
  1094  func TestPrefixToIPv4sEdgeCase(t *testing.T) {
  1095  	prefix := "192.168.1.255/32"
  1096  	expectedIPs := []string{"192.168.1.255"}
  1097  	ips, err := PrefixToIps(prefix, 0)
  1098  	require.Nil(t, err)
  1099  	require.EqualValues(t, expectedIPs, ips)
  1100  }
  1101  
  1102  func TestPrefixToIpsWithMaxIPv4sExceedingRange(t *testing.T) {
  1103  	prefix := "192.168.1.0/30"
  1104  	maxIPs := 10 // Intentionally exceeding the available IPs in the prefix
  1105  	expectedIPs := []string{"192.168.1.0", "192.168.1.1", "192.168.1.2", "192.168.1.3"}
  1106  	ips, err := PrefixToIps(prefix, maxIPs)
  1107  	require.Nil(t, err)
  1108  	require.EqualValues(t, expectedIPs, ips)
  1109  }