github.com/rawahars/moby@v24.0.4+incompatible/libnetwork/osl/sandbox_linux_test.go (about) 1 package osl 2 3 import ( 4 "crypto/rand" 5 "encoding/hex" 6 "io" 7 "net" 8 "os" 9 "path/filepath" 10 "strings" 11 "syscall" 12 "testing" 13 "time" 14 15 "github.com/docker/docker/libnetwork/ns" 16 "github.com/docker/docker/libnetwork/testutils" 17 "github.com/docker/docker/libnetwork/types" 18 "github.com/vishvananda/netlink" 19 "github.com/vishvananda/netlink/nl" 20 "github.com/vishvananda/netns" 21 ) 22 23 const ( 24 vethName1 = "wierdlongname1" 25 vethName2 = "wierdlongname2" 26 vethName3 = "wierdlongname3" 27 vethName4 = "wierdlongname4" 28 sboxIfaceName = "containername" 29 ) 30 31 func generateRandomName(prefix string, size int) (string, error) { 32 id := make([]byte, 32) 33 if _, err := io.ReadFull(rand.Reader, id); err != nil { 34 return "", err 35 } 36 return prefix + hex.EncodeToString(id)[:size], nil 37 } 38 39 func newKey(t *testing.T) (string, error) { 40 name, err := generateRandomName("netns", 12) 41 if err != nil { 42 return "", err 43 } 44 45 name = filepath.Join("/tmp", name) 46 if _, err := os.Create(name); err != nil { 47 return "", err 48 } 49 50 // Set the rpmCleanupPeriod to be low to make the test run quicker 51 gpmLock.Lock() 52 gpmCleanupPeriod = 2 * time.Second 53 gpmLock.Unlock() 54 55 return name, nil 56 } 57 58 func newInfo(hnd *netlink.Handle, t *testing.T) (Sandbox, error) { 59 veth := &netlink.Veth{ 60 LinkAttrs: netlink.LinkAttrs{Name: vethName1, TxQLen: 0}, 61 PeerName: vethName2} 62 if err := hnd.LinkAdd(veth); err != nil { 63 return nil, err 64 } 65 66 // Store the sandbox side pipe interface 67 // This is needed for cleanup on DeleteEndpoint() 68 intf1 := &nwIface{} 69 intf1.srcName = vethName2 70 intf1.dstName = sboxIfaceName 71 72 ip4, addr, err := net.ParseCIDR("192.168.1.100/24") 73 if err != nil { 74 return nil, err 75 } 76 intf1.address = addr 77 intf1.address.IP = ip4 78 79 ip6, addrv6, err := net.ParseCIDR("fe80::2/64") 80 if err != nil { 81 return nil, err 82 } 83 intf1.addressIPv6 = addrv6 84 intf1.addressIPv6.IP = ip6 85 86 _, route, err := net.ParseCIDR("192.168.2.1/32") 87 if err != nil { 88 return nil, err 89 } 90 91 intf1.routes = []*net.IPNet{route} 92 93 intf2 := &nwIface{} 94 intf2.srcName = "testbridge" 95 intf2.dstName = sboxIfaceName 96 intf2.bridge = true 97 98 veth = &netlink.Veth{ 99 LinkAttrs: netlink.LinkAttrs{Name: vethName3, TxQLen: 0}, 100 PeerName: vethName4} 101 102 if err := hnd.LinkAdd(veth); err != nil { 103 return nil, err 104 } 105 106 intf3 := &nwIface{} 107 intf3.srcName = vethName4 108 intf3.dstName = sboxIfaceName 109 intf3.master = "testbridge" 110 111 info := &networkNamespace{iFaces: []*nwIface{intf1, intf2, intf3}} 112 113 info.gw = net.ParseIP("192.168.1.1") 114 info.gwv6 = net.ParseIP("fe80::1") 115 116 return info, nil 117 } 118 119 func verifySandbox(t *testing.T, s Sandbox, ifaceSuffixes []string) { 120 _, ok := s.(*networkNamespace) 121 if !ok { 122 t.Fatalf("The sandbox interface returned is not of type networkNamespace") 123 } 124 125 sbNs, err := netns.GetFromPath(s.Key()) 126 if err != nil { 127 t.Fatalf("Failed top open network namespace path %q: %v", s.Key(), err) 128 } 129 defer sbNs.Close() 130 131 nh, err := netlink.NewHandleAt(sbNs) 132 if err != nil { 133 t.Fatal(err) 134 } 135 defer nh.Close() 136 137 for _, suffix := range ifaceSuffixes { 138 _, err = nh.LinkByName(sboxIfaceName + suffix) 139 if err != nil { 140 t.Fatalf("Could not find the interface %s inside the sandbox: %v", 141 sboxIfaceName+suffix, err) 142 } 143 } 144 } 145 146 func verifyCleanup(t *testing.T, s Sandbox, wait bool) { 147 if wait { 148 time.Sleep(gpmCleanupPeriod * 2) 149 } 150 151 if _, err := os.Stat(s.Key()); err == nil { 152 if wait { 153 t.Fatalf("The sandbox path %s is not getting cleaned up even after twice the cleanup period", s.Key()) 154 } else { 155 t.Fatalf("The sandbox path %s is not cleaned up after running gc", s.Key()) 156 } 157 } 158 } 159 160 func TestDisableIPv6DAD(t *testing.T) { 161 defer testutils.SetupTestOSContext(t)() 162 163 key, err := newKey(t) 164 if err != nil { 165 t.Fatalf("Failed to obtain a key: %v", err) 166 } 167 168 s, err := NewSandbox(key, true, false) 169 if err != nil { 170 t.Fatalf("Failed to create a new sandbox: %v", err) 171 } 172 defer destroyTest(t, s) 173 174 n, ok := s.(*networkNamespace) 175 if !ok { 176 t.Fatal(ok) 177 } 178 nlh := n.nlHandle 179 180 ipv6, _ := types.ParseCIDR("2001:db8::44/64") 181 iface := &nwIface{addressIPv6: ipv6, ns: n, dstName: "sideA"} 182 183 veth := &netlink.Veth{ 184 LinkAttrs: netlink.LinkAttrs{Name: "sideA"}, 185 PeerName: "sideB", 186 } 187 188 err = nlh.LinkAdd(veth) 189 if err != nil { 190 t.Fatal(err) 191 } 192 193 link, err := nlh.LinkByName("sideA") 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 err = setInterfaceIPv6(nlh, link, iface) 199 if err != nil { 200 t.Fatal(err) 201 } 202 203 addrList, err := nlh.AddrList(link, nl.FAMILY_V6) 204 if err != nil { 205 t.Fatal(err) 206 } 207 208 if addrList[0].Flags&syscall.IFA_F_NODAD == 0 { 209 t.Fatalf("Unexpected interface flags: 0x%x. Expected to contain 0x%x", addrList[0].Flags, syscall.IFA_F_NODAD) 210 } 211 } 212 213 func destroyTest(t *testing.T, s Sandbox) { 214 if err := s.Destroy(); err != nil { 215 t.Log(err) 216 } 217 } 218 219 func TestSetInterfaceIP(t *testing.T) { 220 defer testutils.SetupTestOSContext(t)() 221 222 key, err := newKey(t) 223 if err != nil { 224 t.Fatalf("Failed to obtain a key: %v", err) 225 } 226 227 s, err := NewSandbox(key, true, false) 228 if err != nil { 229 t.Fatalf("Failed to create a new sandbox: %v", err) 230 } 231 defer destroyTest(t, s) 232 233 n, ok := s.(*networkNamespace) 234 if !ok { 235 t.Fatal(ok) 236 } 237 nlh := n.nlHandle 238 239 ipv4, _ := types.ParseCIDR("172.30.0.33/24") 240 ipv6, _ := types.ParseCIDR("2001:db8::44/64") 241 iface := &nwIface{address: ipv4, addressIPv6: ipv6, ns: n, dstName: "sideA"} 242 243 if err := nlh.LinkAdd(&netlink.Veth{ 244 LinkAttrs: netlink.LinkAttrs{Name: "sideA"}, 245 PeerName: "sideB", 246 }); err != nil { 247 t.Fatal(err) 248 } 249 250 linkA, err := nlh.LinkByName("sideA") 251 if err != nil { 252 t.Fatal(err) 253 } 254 255 linkB, err := nlh.LinkByName("sideB") 256 if err != nil { 257 t.Fatal(err) 258 } 259 260 if err := nlh.LinkSetUp(linkA); err != nil { 261 t.Fatal(err) 262 } 263 264 if err := nlh.LinkSetUp(linkB); err != nil { 265 t.Fatal(err) 266 } 267 268 if err := setInterfaceIP(nlh, linkA, iface); err != nil { 269 t.Fatal(err) 270 } 271 272 if err := setInterfaceIPv6(nlh, linkA, iface); err != nil { 273 t.Fatal(err) 274 } 275 276 err = setInterfaceIP(nlh, linkB, iface) 277 if err == nil { 278 t.Fatalf("Expected route conflict error, but succeeded") 279 } 280 if !strings.Contains(err.Error(), "conflicts with existing route") { 281 t.Fatalf("Unexpected error: %v", err) 282 } 283 284 err = setInterfaceIPv6(nlh, linkB, iface) 285 if err == nil { 286 t.Fatalf("Expected route conflict error, but succeeded") 287 } 288 if !strings.Contains(err.Error(), "conflicts with existing route") { 289 t.Fatalf("Unexpected error: %v", err) 290 } 291 } 292 293 func TestLiveRestore(t *testing.T) { 294 defer testutils.SetupTestOSContext(t)() 295 296 key, err := newKey(t) 297 if err != nil { 298 t.Fatalf("Failed to obtain a key: %v", err) 299 } 300 301 s, err := NewSandbox(key, true, false) 302 if err != nil { 303 t.Fatalf("Failed to create a new sandbox: %v", err) 304 } 305 defer destroyTest(t, s) 306 307 n, ok := s.(*networkNamespace) 308 if !ok { 309 t.Fatal(ok) 310 } 311 nlh := n.nlHandle 312 313 ipv4, _ := types.ParseCIDR("172.30.0.33/24") 314 ipv6, _ := types.ParseCIDR("2001:db8::44/64") 315 iface := &nwIface{address: ipv4, addressIPv6: ipv6, ns: n, dstName: "sideA"} 316 317 if err := nlh.LinkAdd(&netlink.Veth{ 318 LinkAttrs: netlink.LinkAttrs{Name: "sideA"}, 319 PeerName: "sideB", 320 }); err != nil { 321 t.Fatal(err) 322 } 323 324 linkA, err := nlh.LinkByName("sideA") 325 if err != nil { 326 t.Fatal(err) 327 } 328 329 linkB, err := nlh.LinkByName("sideB") 330 if err != nil { 331 t.Fatal(err) 332 } 333 334 if err := nlh.LinkSetUp(linkA); err != nil { 335 t.Fatal(err) 336 } 337 338 if err := nlh.LinkSetUp(linkB); err != nil { 339 t.Fatal(err) 340 } 341 342 if err := setInterfaceIP(nlh, linkA, iface); err != nil { 343 t.Fatal(err) 344 } 345 346 if err := setInterfaceIPv6(nlh, linkA, iface); err != nil { 347 t.Fatal(err) 348 } 349 350 err = setInterfaceIP(nlh, linkB, iface) 351 if err == nil { 352 t.Fatalf("Expected route conflict error, but succeeded") 353 } 354 if !strings.Contains(err.Error(), "conflicts with existing route") { 355 t.Fatalf("Unexpected error: %v", err) 356 } 357 358 err = setInterfaceIPv6(nlh, linkB, iface) 359 if err == nil { 360 t.Fatalf("Expected route conflict error, but succeeded") 361 } 362 if !strings.Contains(err.Error(), "conflicts with existing route") { 363 t.Fatalf("Unexpected error: %v", err) 364 } 365 366 // Create newsandbox with Restore - TRUE 367 s, err = NewSandbox(key, true, true) 368 if err != nil { 369 t.Fatalf("Failed to create a new sandbox: %v", err) 370 } 371 defer destroyTest(t, s) 372 373 // Check if the IPV4 & IPV6 entry present 374 // If present , we should get error in below call 375 // It shows us , we don't delete any config in live-restore case 376 if err := setInterfaceIPv6(nlh, linkA, iface); err == nil { 377 t.Fatalf("Expected route conflict error, but succeeded for IPV6 ") 378 } 379 if err := setInterfaceIP(nlh, linkA, iface); err == nil { 380 t.Fatalf("Expected route conflict error, but succeeded for IPV4 ") 381 } 382 } 383 384 func TestSandboxCreate(t *testing.T) { 385 defer testutils.SetupTestOSContext(t)() 386 387 key, err := newKey(t) 388 if err != nil { 389 t.Fatalf("Failed to obtain a key: %v", err) 390 } 391 392 s, err := NewSandbox(key, true, false) 393 if err != nil { 394 t.Fatalf("Failed to create a new sandbox: %v", err) 395 } 396 397 if s.Key() != key { 398 t.Fatalf("s.Key() returned %s. Expected %s", s.Key(), key) 399 } 400 401 tbox, err := newInfo(ns.NlHandle(), t) 402 if err != nil { 403 t.Fatalf("Failed to generate new sandbox info: %v", err) 404 } 405 406 for _, i := range tbox.Info().Interfaces() { 407 err = s.AddInterface(i.SrcName(), i.DstName(), 408 tbox.InterfaceOptions().Bridge(i.Bridge()), 409 tbox.InterfaceOptions().Address(i.Address()), 410 tbox.InterfaceOptions().AddressIPv6(i.AddressIPv6())) 411 if err != nil { 412 t.Fatalf("Failed to add interfaces to sandbox: %v", err) 413 } 414 } 415 416 err = s.SetGateway(tbox.Info().Gateway()) 417 if err != nil { 418 t.Fatalf("Failed to set gateway to sandbox: %v", err) 419 } 420 421 err = s.SetGatewayIPv6(tbox.Info().GatewayIPv6()) 422 if err != nil { 423 t.Fatalf("Failed to set ipv6 gateway to sandbox: %v", err) 424 } 425 426 verifySandbox(t, s, []string{"0", "1", "2"}) 427 428 err = s.Destroy() 429 if err != nil { 430 t.Fatal(err) 431 } 432 verifyCleanup(t, s, true) 433 } 434 435 func TestSandboxCreateTwice(t *testing.T) { 436 defer testutils.SetupTestOSContext(t)() 437 438 key, err := newKey(t) 439 if err != nil { 440 t.Fatalf("Failed to obtain a key: %v", err) 441 } 442 443 _, err = NewSandbox(key, true, false) 444 if err != nil { 445 t.Fatalf("Failed to create a new sandbox: %v", err) 446 } 447 448 // Create another sandbox with the same key to see if we handle it 449 // gracefully. 450 s, err := NewSandbox(key, true, false) 451 if err != nil { 452 t.Fatalf("Failed to create a new sandbox: %v", err) 453 } 454 455 err = s.Destroy() 456 if err != nil { 457 t.Fatal(err) 458 } 459 GC() 460 verifyCleanup(t, s, false) 461 } 462 463 func TestSandboxGC(t *testing.T) { 464 key, err := newKey(t) 465 if err != nil { 466 t.Fatalf("Failed to obtain a key: %v", err) 467 } 468 469 s, err := NewSandbox(key, true, false) 470 if err != nil { 471 t.Fatalf("Failed to create a new sandbox: %v", err) 472 } 473 474 err = s.Destroy() 475 if err != nil { 476 t.Fatal(err) 477 } 478 479 GC() 480 verifyCleanup(t, s, false) 481 } 482 483 func TestAddRemoveInterface(t *testing.T) { 484 defer testutils.SetupTestOSContext(t)() 485 486 key, err := newKey(t) 487 if err != nil { 488 t.Fatalf("Failed to obtain a key: %v", err) 489 } 490 491 s, err := NewSandbox(key, true, false) 492 if err != nil { 493 t.Fatalf("Failed to create a new sandbox: %v", err) 494 } 495 496 if s.Key() != key { 497 t.Fatalf("s.Key() returned %s. Expected %s", s.Key(), key) 498 } 499 500 tbox, err := newInfo(ns.NlHandle(), t) 501 if err != nil { 502 t.Fatalf("Failed to generate new sandbox info: %v", err) 503 } 504 505 for _, i := range tbox.Info().Interfaces() { 506 err = s.AddInterface(i.SrcName(), i.DstName(), 507 tbox.InterfaceOptions().Bridge(i.Bridge()), 508 tbox.InterfaceOptions().Address(i.Address()), 509 tbox.InterfaceOptions().AddressIPv6(i.AddressIPv6())) 510 if err != nil { 511 t.Fatalf("Failed to add interfaces to sandbox: %v", err) 512 } 513 } 514 515 verifySandbox(t, s, []string{"0", "1", "2"}) 516 517 interfaces := s.Info().Interfaces() 518 if err := interfaces[0].Remove(); err != nil { 519 t.Fatalf("Failed to remove interfaces from sandbox: %v", err) 520 } 521 522 verifySandbox(t, s, []string{"1", "2"}) 523 524 i := tbox.Info().Interfaces()[0] 525 if err := s.AddInterface(i.SrcName(), i.DstName(), 526 tbox.InterfaceOptions().Bridge(i.Bridge()), 527 tbox.InterfaceOptions().Address(i.Address()), 528 tbox.InterfaceOptions().AddressIPv6(i.AddressIPv6())); err != nil { 529 t.Fatalf("Failed to add interfaces to sandbox: %v", err) 530 } 531 532 verifySandbox(t, s, []string{"1", "2", "3"}) 533 534 err = s.Destroy() 535 if err != nil { 536 t.Fatal(err) 537 } 538 539 GC() 540 verifyCleanup(t, s, false) 541 }