github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/netutils/utils_linux_test.go (about) 1 package netutils 2 3 import ( 4 "bytes" 5 "fmt" 6 "net" 7 "strings" 8 "testing" 9 10 "github.com/Prakhar-Agarwal-byte/moby/internal/testutils/netnsutils" 11 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/ipamutils" 12 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/types" 13 "github.com/vishvananda/netlink" 14 "gotest.tools/v3/assert" 15 is "gotest.tools/v3/assert/cmp" 16 ) 17 18 func TestNonOverlappingNameservers(t *testing.T) { 19 network := &net.IPNet{ 20 IP: []byte{192, 168, 0, 1}, 21 Mask: []byte{255, 255, 255, 0}, 22 } 23 nameservers := []string{ 24 "127.0.0.1/32", 25 } 26 27 if err := CheckNameserverOverlaps(nameservers, network); err != nil { 28 t.Fatal(err) 29 } 30 } 31 32 func TestOverlappingNameservers(t *testing.T) { 33 network := &net.IPNet{ 34 IP: []byte{192, 168, 0, 1}, 35 Mask: []byte{255, 255, 255, 0}, 36 } 37 nameservers := []string{ 38 "192.168.0.1/32", 39 } 40 41 if err := CheckNameserverOverlaps(nameservers, network); err == nil { 42 t.Fatalf("Expected error %s got %s", ErrNetworkOverlapsWithNameservers, err) 43 } 44 } 45 46 func TestCheckRouteOverlaps(t *testing.T) { 47 networkGetRoutesFct = func(netlink.Link, int) ([]netlink.Route, error) { 48 routesData := []string{"10.0.2.0/32", "10.0.3.0/24", "10.0.42.0/24", "172.16.42.0/24", "192.168.142.0/24"} 49 routes := []netlink.Route{} 50 for _, addr := range routesData { 51 _, netX, _ := net.ParseCIDR(addr) 52 routes = append(routes, netlink.Route{Dst: netX, Scope: netlink.SCOPE_LINK}) 53 } 54 // Add a route with a scope which should not overlap 55 _, netX, _ := net.ParseCIDR("10.0.5.0/24") 56 routes = append(routes, netlink.Route{Dst: netX, Scope: netlink.SCOPE_UNIVERSE}) 57 return routes, nil 58 } 59 defer func() { networkGetRoutesFct = nil }() 60 61 _, netX, _ := net.ParseCIDR("172.16.0.1/24") 62 if err := CheckRouteOverlaps(netX); err != nil { 63 t.Fatal(err) 64 } 65 66 _, netX, _ = net.ParseCIDR("10.0.2.0/24") 67 if err := CheckRouteOverlaps(netX); err == nil { 68 t.Fatal("10.0.2.0/24 and 10.0.2.0 should overlap but it doesn't") 69 } 70 71 _, netX, _ = net.ParseCIDR("10.0.5.0/24") 72 if err := CheckRouteOverlaps(netX); err != nil { 73 t.Fatal("10.0.5.0/24 and 10.0.5.0 with scope UNIVERSE should not overlap but it does") 74 } 75 } 76 77 func TestCheckNameserverOverlaps(t *testing.T) { 78 nameservers := []string{"10.0.2.3/32", "192.168.102.1/32"} 79 80 _, netX, _ := net.ParseCIDR("10.0.2.3/32") 81 82 if err := CheckNameserverOverlaps(nameservers, netX); err == nil { 83 t.Fatalf("%s should overlap 10.0.2.3/32 but doesn't", netX) 84 } 85 86 _, netX, _ = net.ParseCIDR("192.168.102.2/32") 87 88 if err := CheckNameserverOverlaps(nameservers, netX); err != nil { 89 t.Fatalf("%s should not overlap %v but it does", netX, nameservers) 90 } 91 } 92 93 func AssertOverlap(CIDRx string, CIDRy string, t *testing.T) { 94 _, netX, _ := net.ParseCIDR(CIDRx) 95 _, netY, _ := net.ParseCIDR(CIDRy) 96 if !NetworkOverlaps(netX, netY) { 97 t.Errorf("%v and %v should overlap", netX, netY) 98 } 99 } 100 101 func AssertNoOverlap(CIDRx string, CIDRy string, t *testing.T) { 102 _, netX, _ := net.ParseCIDR(CIDRx) 103 _, netY, _ := net.ParseCIDR(CIDRy) 104 if NetworkOverlaps(netX, netY) { 105 t.Errorf("%v and %v should not overlap", netX, netY) 106 } 107 } 108 109 func TestNetworkOverlaps(t *testing.T) { 110 // netY starts at same IP and ends within netX 111 AssertOverlap("172.16.0.1/24", "172.16.0.1/25", t) 112 // netY starts within netX and ends at same IP 113 AssertOverlap("172.16.0.1/24", "172.16.0.128/25", t) 114 // netY starts and ends within netX 115 AssertOverlap("172.16.0.1/24", "172.16.0.64/25", t) 116 // netY starts at same IP and ends outside of netX 117 AssertOverlap("172.16.0.1/24", "172.16.0.1/23", t) 118 // netY starts before and ends at same IP of netX 119 AssertOverlap("172.16.1.1/24", "172.16.0.1/23", t) 120 // netY starts before and ends outside of netX 121 AssertOverlap("172.16.1.1/24", "172.16.0.1/22", t) 122 // netY starts and ends before netX 123 AssertNoOverlap("172.16.1.1/25", "172.16.0.1/24", t) 124 // netX starts and ends before netY 125 AssertNoOverlap("172.16.1.1/25", "172.16.2.1/24", t) 126 } 127 128 func TestNetworkRange(t *testing.T) { 129 // Simple class C test 130 _, network, _ := net.ParseCIDR("192.168.0.1/24") 131 first, last := NetworkRange(network) 132 if !first.Equal(net.ParseIP("192.168.0.0")) { 133 t.Error(first.String()) 134 } 135 if !last.Equal(net.ParseIP("192.168.0.255")) { 136 t.Error(last.String()) 137 } 138 139 // Class A test 140 _, network, _ = net.ParseCIDR("10.0.0.1/8") 141 first, last = NetworkRange(network) 142 if !first.Equal(net.ParseIP("10.0.0.0")) { 143 t.Error(first.String()) 144 } 145 if !last.Equal(net.ParseIP("10.255.255.255")) { 146 t.Error(last.String()) 147 } 148 149 // Class A, random IP address 150 _, network, _ = net.ParseCIDR("10.1.2.3/8") 151 first, last = NetworkRange(network) 152 if !first.Equal(net.ParseIP("10.0.0.0")) { 153 t.Error(first.String()) 154 } 155 if !last.Equal(net.ParseIP("10.255.255.255")) { 156 t.Error(last.String()) 157 } 158 159 // 32bit mask 160 _, network, _ = net.ParseCIDR("10.1.2.3/32") 161 first, last = NetworkRange(network) 162 if !first.Equal(net.ParseIP("10.1.2.3")) { 163 t.Error(first.String()) 164 } 165 if !last.Equal(net.ParseIP("10.1.2.3")) { 166 t.Error(last.String()) 167 } 168 169 // 31bit mask 170 _, network, _ = net.ParseCIDR("10.1.2.3/31") 171 first, last = NetworkRange(network) 172 if !first.Equal(net.ParseIP("10.1.2.2")) { 173 t.Error(first.String()) 174 } 175 if !last.Equal(net.ParseIP("10.1.2.3")) { 176 t.Error(last.String()) 177 } 178 179 // 26bit mask 180 _, network, _ = net.ParseCIDR("10.1.2.3/26") 181 first, last = NetworkRange(network) 182 if !first.Equal(net.ParseIP("10.1.2.0")) { 183 t.Error(first.String()) 184 } 185 if !last.Equal(net.ParseIP("10.1.2.63")) { 186 t.Error(last.String()) 187 } 188 } 189 190 // Test veth name generation "veth"+rand (e.g.veth0f60e2c) 191 func TestGenerateRandomName(t *testing.T) { 192 const vethPrefix = "veth" 193 const vethLen = len(vethPrefix) + 7 194 195 testCases := []struct { 196 prefix string 197 length int 198 error bool 199 }{ 200 {vethPrefix, -1, true}, 201 {vethPrefix, 0, true}, 202 {vethPrefix, len(vethPrefix) - 1, true}, 203 {vethPrefix, len(vethPrefix), true}, 204 {vethPrefix, len(vethPrefix) + 1, false}, 205 {vethPrefix, 255, false}, 206 } 207 for _, tc := range testCases { 208 t.Run(fmt.Sprintf("prefix=%s/length=%d", tc.prefix, tc.length), func(t *testing.T) { 209 name, err := GenerateRandomName(tc.prefix, tc.length) 210 if tc.error { 211 assert.Check(t, is.ErrorContains(err, "invalid length")) 212 } else { 213 assert.NilError(t, err) 214 assert.Check(t, strings.HasPrefix(name, tc.prefix), "Expected name to start with %s", tc.prefix) 215 assert.Check(t, is.Equal(len(name), tc.length), "Expected %d characters, instead received %d characters", tc.length, len(name)) 216 } 217 }) 218 } 219 220 var randomNames [16]string 221 for i := range randomNames { 222 randomName, err := GenerateRandomName(vethPrefix, vethLen) 223 assert.NilError(t, err) 224 225 for _, oldName := range randomNames { 226 if randomName == oldName { 227 t.Fatalf("Duplicate random name generated: %s", randomName) 228 } 229 } 230 231 randomNames[i] = randomName 232 } 233 } 234 235 // Test mac generation. 236 func TestUtilGenerateRandomMAC(t *testing.T) { 237 mac1 := GenerateRandomMAC() 238 mac2 := GenerateRandomMAC() 239 // ensure bytes are unique 240 if bytes.Equal(mac1, mac2) { 241 t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2) 242 } 243 // existing tests check string functionality so keeping the pattern 244 if mac1.String() == mac2.String() { 245 t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2) 246 } 247 } 248 249 func TestNetworkRequest(t *testing.T) { 250 defer netnsutils.SetupTestOSContext(t)() 251 252 nw, err := FindAvailableNetwork(ipamutils.GetLocalScopeDefaultNetworks()) 253 if err != nil { 254 t.Fatal(err) 255 } 256 257 var found bool 258 for _, exp := range ipamutils.GetLocalScopeDefaultNetworks() { 259 if types.CompareIPNet(exp, nw) { 260 found = true 261 break 262 } 263 } 264 265 if !found { 266 t.Fatalf("Found unexpected broad network %s", nw) 267 } 268 269 nw, err = FindAvailableNetwork(ipamutils.GetGlobalScopeDefaultNetworks()) 270 if err != nil { 271 t.Fatal(err) 272 } 273 274 found = false 275 for _, exp := range ipamutils.GetGlobalScopeDefaultNetworks() { 276 if types.CompareIPNet(exp, nw) { 277 found = true 278 break 279 } 280 } 281 282 if !found { 283 t.Fatalf("Found unexpected granular network %s", nw) 284 } 285 286 // Add iface and ssert returned address on request 287 createInterface(t, "test", "172.17.42.1/16") 288 289 _, exp, err := net.ParseCIDR("172.18.0.0/16") 290 if err != nil { 291 t.Fatal(err) 292 } 293 nw, err = FindAvailableNetwork(ipamutils.GetLocalScopeDefaultNetworks()) 294 if err != nil { 295 t.Fatal(err) 296 } 297 if !types.CompareIPNet(exp, nw) { 298 t.Fatalf("expected %s. got %s", exp, nw) 299 } 300 } 301 302 func createInterface(t *testing.T, name string, nws ...string) { 303 // Add interface 304 link := &netlink.Bridge{ 305 LinkAttrs: netlink.LinkAttrs{ 306 Name: "test", 307 }, 308 } 309 bips := []*net.IPNet{} 310 for _, nw := range nws { 311 bip, err := types.ParseCIDR(nw) 312 if err != nil { 313 t.Fatal(err) 314 } 315 bips = append(bips, bip) 316 } 317 if err := netlink.LinkAdd(link); err != nil { 318 t.Fatalf("Failed to create interface via netlink: %v", err) 319 } 320 for _, bip := range bips { 321 if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: bip}); err != nil { 322 t.Fatal(err) 323 } 324 } 325 if err := netlink.LinkSetUp(link); err != nil { 326 t.Fatal(err) 327 } 328 }