github.com/cilium/cilium@v1.16.2/pkg/counter/prefixes_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package counter 5 6 import ( 7 "net" 8 "net/netip" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestReferenceTracker(t *testing.T) { 15 v4Prefixes := []netip.Prefix{ 16 netip.MustParsePrefix("0.0.0.0/0"), 17 netip.MustParsePrefix("192.0.0.0/15"), 18 netip.MustParsePrefix("192.0.0.0/15"), 19 netip.MustParsePrefix("192.0.2.2/31"), 20 netip.MustParsePrefix("192.0.2.3/32"), 21 } 22 v4PrefixesLengths := map[int]int{ 23 0: 1, 24 15: 2, 25 31: 1, 26 32: 1, 27 } 28 29 result := NewPrefixLengthCounter(128, 32) 30 31 // Expected output is the combination of defaults and the above prefixes. 32 expectedPrefixLengths := make(IntCounter, len(v4PrefixesLengths)) 33 for k, v := range v4PrefixesLengths { 34 expectedPrefixLengths[k] += v 35 } 36 // New prefixes are added (return true) 37 changed, err := result.Add(v4Prefixes) 38 require.NoError(t, err) 39 require.True(t, changed) 40 require.Equal(t, expectedPrefixLengths, result.v4) 41 42 // When we add the prefixes again, we should increase the reference 43 // counts appropriately 44 for k, v := range v4PrefixesLengths { 45 expectedPrefixLengths[k] += v 46 } 47 // This time, there are no new prefix lengths (return false). 48 changed, err = result.Add(v4Prefixes) 49 require.NoError(t, err) 50 require.False(t, changed) 51 require.Equal(t, expectedPrefixLengths, result.v4) 52 53 // Delete the /15 prefix and see that it is removed and doesn't affect 54 // other counts 55 prefixes15 := []netip.Prefix{ 56 netip.MustParsePrefix("192.0.0.0/15"), 57 } 58 expectedPrefixLengths[15]-- 59 require.False(t, result.Delete(prefixes15)) 60 require.Equal(t, expectedPrefixLengths, result.v4) 61 62 // Delete some prefix lengths 63 for k, v := range v4PrefixesLengths { 64 expectedPrefixLengths[k] -= v 65 } 66 // No change in prefix lengths; each 'prefixes' was referenced twice. 67 require.False(t, result.Delete(v4Prefixes)) 68 require.Equal(t, expectedPrefixLengths, result.v4) 69 70 // Re-add the /32 prefix and see that it is added back properly. 71 expectedPrefixLengths[15]++ 72 changed, err = result.Add(prefixes15) 73 require.NoError(t, err) 74 require.False(t, changed) 75 require.Equal(t, expectedPrefixLengths, result.v4) 76 77 // When removing the 'prefixes' again, return true and the set of 78 // prefixes should be empty 79 require.True(t, result.Delete(v4Prefixes)) 80 require.Equal(t, IntCounter{}, result.v4) 81 82 // Add back the v4 prefixes while we add v6 prefixes. 83 changed, err = result.Add(v4Prefixes) 84 require.NoError(t, err) 85 require.True(t, changed) 86 require.Equal(t, expectedPrefixLengths, result.v4) 87 88 v6Prefixes := []netip.Prefix{ 89 netip.MustParsePrefix("::/0"), 90 netip.MustParsePrefix("FD33:DEAD:BEEF:CAFE::/76"), 91 netip.MustParsePrefix("FD33:DEAD:BEEF:CAFE::/96"), 92 netip.MustParsePrefix("fd33:dead:beef:cafe::91b2:b600/120"), 93 } 94 v6PrefixesLengths := map[int]int{ 95 0: 1, 96 76: 1, 97 96: 1, 98 120: 1, 99 } 100 101 expectedPrefixLengths = make(IntCounter, len(v6PrefixesLengths)) 102 103 // Add the v6 prefixes (changed: true) 104 for k, v := range v6PrefixesLengths { 105 expectedPrefixLengths[k] = v 106 } 107 changed, err = result.Add(v6Prefixes) 108 require.NoError(t, err) 109 require.True(t, changed) 110 require.Equal(t, expectedPrefixLengths, result.v6) 111 112 // Add the v6 prefixes again (changed: false) 113 for k, v := range v6PrefixesLengths { 114 expectedPrefixLengths[k] += v 115 } 116 changed, err = result.Add(v6Prefixes) 117 require.NoError(t, err) 118 require.False(t, changed) 119 require.Equal(t, expectedPrefixLengths, result.v6) 120 121 // Now, remove them (changed: false) 122 for k, v := range v6PrefixesLengths { 123 expectedPrefixLengths[k] -= v 124 } 125 require.False(t, result.Delete(v6Prefixes)) 126 require.Equal(t, expectedPrefixLengths, result.v6) 127 128 // Delete them again (changed: true) 129 require.True(t, result.Delete(v6Prefixes)) 130 require.Equal(t, IntCounter{}, result.v6) 131 132 // Our v4 prefixes should still be here, unchanged 133 expectedPrefixLengths = make(map[int]int, len(v4PrefixesLengths)) 134 for k, v := range v4PrefixesLengths { 135 expectedPrefixLengths[k] += v 136 } 137 require.Equal(t, expectedPrefixLengths, result.v4) 138 } 139 140 func TestCheckLimits(t *testing.T) { 141 result := NewPrefixLengthCounter(4, 4) 142 require.Nil(t, checkLimits(0, 4, result.maxUniquePrefixes4)) 143 require.NotNil(t, checkLimits(0, 5, result.maxUniquePrefixes4)) 144 require.Nil(t, checkLimits(0, 4, result.maxUniquePrefixes6)) 145 require.NotNil(t, checkLimits(0, 5, result.maxUniquePrefixes6)) 146 147 prefixes := []netip.Prefix{ 148 netip.MustParsePrefix("0.0.0.0/0"), 149 netip.MustParsePrefix("192.0.0.0/15"), 150 netip.MustParsePrefix("192.0.2.2/31"), 151 netip.MustParsePrefix("192.0.2.3/32"), 152 } 153 changed, err := result.Add(prefixes) 154 require.NoError(t, err) 155 require.True(t, changed) 156 157 changed, err = result.Add([]netip.Prefix{netip.MustParsePrefix("192.0.0.0/8")}) 158 require.Error(t, err) 159 require.False(t, changed) 160 } 161 162 func TestToBPFData(t *testing.T) { 163 result := NewPrefixLengthCounter(42, 32) 164 165 prefixes := []string{ 166 "192.0.2.0/24", 167 "192.0.2.0/32", 168 "192.0.64.0/20", 169 } 170 prefixesToAdd := []netip.Prefix{} 171 for _, prefix := range prefixes { 172 net := netip.MustParsePrefix(prefix) 173 prefixesToAdd = append(prefixesToAdd, net) 174 } 175 176 _, err := result.Add(prefixesToAdd) 177 require.NoError(t, err) 178 179 s6, s4 := result.ToBPFData() 180 require.Equal(t, []int{}, s6) 181 require.Equal(t, []int{32, 24, 20}, s4) 182 } 183 184 func TestDefaultPrefixLengthCounter(t *testing.T) { 185 result := DefaultPrefixLengthCounter() 186 require.Equal(t, 1, result.v4[0]) 187 require.Equal(t, 1, result.v6[0]) 188 require.Equal(t, 1, result.v4[net.IPv4len*8]) 189 require.Equal(t, 1, result.v6[net.IPv6len*8]) 190 }