github.com/rawahars/moby@v24.0.4+incompatible/libnetwork/drivers/bridge/bridge_test.go (about) 1 //go:build linux 2 // +build linux 3 4 package bridge 5 6 import ( 7 "bytes" 8 "encoding/json" 9 "fmt" 10 "net" 11 "regexp" 12 "strconv" 13 "testing" 14 15 "github.com/docker/docker/libnetwork/driverapi" 16 "github.com/docker/docker/libnetwork/ipamutils" 17 "github.com/docker/docker/libnetwork/iptables" 18 "github.com/docker/docker/libnetwork/netlabel" 19 "github.com/docker/docker/libnetwork/netutils" 20 "github.com/docker/docker/libnetwork/options" 21 "github.com/docker/docker/libnetwork/portallocator" 22 "github.com/docker/docker/libnetwork/testutils" 23 "github.com/docker/docker/libnetwork/types" 24 "github.com/vishvananda/netlink" 25 ) 26 27 func TestEndpointMarshalling(t *testing.T) { 28 ip1, _ := types.ParseCIDR("172.22.0.9/16") 29 ip2, _ := types.ParseCIDR("2001:db8::9") 30 mac, _ := net.ParseMAC("ac:bd:24:57:66:77") 31 e := &bridgeEndpoint{ 32 id: "d2c015a1fe5930650cbcd50493efba0500bcebd8ee1f4401a16319f8a567de33", 33 nid: "ee33fbb43c323f1920b6b35a0101552ac22ede960d0e5245e9738bccc68b2415", 34 addr: ip1, 35 addrv6: ip2, 36 macAddress: mac, 37 srcName: "veth123456", 38 config: &endpointConfiguration{MacAddress: mac}, 39 containerConfig: &containerConfiguration{ 40 ParentEndpoints: []string{"one", "due", "three"}, 41 ChildEndpoints: []string{"four", "five", "six"}, 42 }, 43 extConnConfig: &connectivityConfiguration{ 44 ExposedPorts: []types.TransportPort{ 45 { 46 Proto: 6, 47 Port: uint16(18), 48 }, 49 }, 50 PortBindings: []types.PortBinding{ 51 { 52 Proto: 6, 53 IP: net.ParseIP("17210.33.9.56"), 54 Port: uint16(18), 55 HostPort: uint16(3000), 56 HostPortEnd: uint16(14000), 57 }, 58 }, 59 }, 60 portMapping: []types.PortBinding{ 61 { 62 Proto: 17, 63 IP: net.ParseIP("172.33.9.56"), 64 Port: uint16(99), 65 HostIP: net.ParseIP("10.10.100.2"), 66 HostPort: uint16(9900), 67 HostPortEnd: uint16(10000), 68 }, 69 { 70 Proto: 6, 71 IP: net.ParseIP("171.33.9.56"), 72 Port: uint16(55), 73 HostIP: net.ParseIP("10.11.100.2"), 74 HostPort: uint16(5500), 75 HostPortEnd: uint16(55000), 76 }, 77 }, 78 } 79 80 b, err := json.Marshal(e) 81 if err != nil { 82 t.Fatal(err) 83 } 84 85 ee := &bridgeEndpoint{} 86 err = json.Unmarshal(b, ee) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 if e.id != ee.id || e.nid != ee.nid || e.srcName != ee.srcName || !bytes.Equal(e.macAddress, ee.macAddress) || 92 !types.CompareIPNet(e.addr, ee.addr) || !types.CompareIPNet(e.addrv6, ee.addrv6) || 93 !compareEpConfig(e.config, ee.config) || 94 !compareContainerConfig(e.containerConfig, ee.containerConfig) || 95 !compareConnConfig(e.extConnConfig, ee.extConnConfig) || 96 !compareBindings(e.portMapping, ee.portMapping) { 97 t.Fatalf("JSON marsh/unmarsh failed.\nOriginal:\n%#v\nDecoded:\n%#v", e, ee) 98 } 99 } 100 101 func compareEpConfig(a, b *endpointConfiguration) bool { 102 if a == b { 103 return true 104 } 105 if a == nil || b == nil { 106 return false 107 } 108 return bytes.Equal(a.MacAddress, b.MacAddress) 109 } 110 111 func compareContainerConfig(a, b *containerConfiguration) bool { 112 if a == b { 113 return true 114 } 115 if a == nil || b == nil { 116 return false 117 } 118 if len(a.ParentEndpoints) != len(b.ParentEndpoints) || 119 len(a.ChildEndpoints) != len(b.ChildEndpoints) { 120 return false 121 } 122 for i := 0; i < len(a.ParentEndpoints); i++ { 123 if a.ParentEndpoints[i] != b.ParentEndpoints[i] { 124 return false 125 } 126 } 127 for i := 0; i < len(a.ChildEndpoints); i++ { 128 if a.ChildEndpoints[i] != b.ChildEndpoints[i] { 129 return false 130 } 131 } 132 return true 133 } 134 135 func compareConnConfig(a, b *connectivityConfiguration) bool { 136 if a == b { 137 return true 138 } 139 if a == nil || b == nil { 140 return false 141 } 142 if len(a.ExposedPorts) != len(b.ExposedPorts) || 143 len(a.PortBindings) != len(b.PortBindings) { 144 return false 145 } 146 for i := 0; i < len(a.ExposedPorts); i++ { 147 if !a.ExposedPorts[i].Equal(&b.ExposedPorts[i]) { 148 return false 149 } 150 } 151 for i := 0; i < len(a.PortBindings); i++ { 152 if !a.PortBindings[i].Equal(&b.PortBindings[i]) { 153 return false 154 } 155 } 156 return true 157 } 158 159 func compareBindings(a, b []types.PortBinding) bool { 160 if len(a) != len(b) { 161 return false 162 } 163 for i := 0; i < len(a); i++ { 164 if !a[i].Equal(&b[i]) { 165 return false 166 } 167 } 168 return true 169 } 170 171 func getIPv4Data(t *testing.T, iface string) []driverapi.IPAMData { 172 ipd := driverapi.IPAMData{AddressSpace: "full"} 173 nw, err := netutils.FindAvailableNetwork(ipamutils.GetLocalScopeDefaultNetworks()) 174 if err != nil { 175 t.Fatal(err) 176 } 177 ipd.Pool = nw 178 // Set network gateway to X.X.X.1 179 ipd.Gateway = types.GetIPNetCopy(nw) 180 ipd.Gateway.IP[len(ipd.Gateway.IP)-1] = 1 181 return []driverapi.IPAMData{ipd} 182 } 183 184 func TestCreateFullOptions(t *testing.T) { 185 defer testutils.SetupTestOSContext(t)() 186 d := newDriver() 187 188 config := &configuration{ 189 EnableIPForwarding: true, 190 EnableIPTables: true, 191 } 192 193 // Test this scenario: Default gw address does not belong to 194 // container network and it's greater than bridge address 195 cnw, _ := types.ParseCIDR("172.16.122.0/24") 196 bnw, _ := types.ParseCIDR("172.16.0.0/24") 197 br, _ := types.ParseCIDR("172.16.0.1/16") 198 defgw, _ := types.ParseCIDR("172.16.0.100/16") 199 200 genericOption := make(map[string]interface{}) 201 genericOption[netlabel.GenericData] = config 202 203 if err := d.configure(genericOption); err != nil { 204 t.Fatalf("Failed to setup driver config: %v", err) 205 } 206 207 netOption := make(map[string]interface{}) 208 netOption[netlabel.EnableIPv6] = true 209 netOption[netlabel.GenericData] = &networkConfiguration{ 210 BridgeName: DefaultBridgeName, 211 } 212 213 ipdList := []driverapi.IPAMData{ 214 { 215 Pool: bnw, 216 Gateway: br, 217 AuxAddresses: map[string]*net.IPNet{DefaultGatewayV4AuxKey: defgw}, 218 }, 219 } 220 err := d.CreateNetwork("dummy", netOption, nil, ipdList, nil) 221 if err != nil { 222 t.Fatalf("Failed to create bridge: %v", err) 223 } 224 225 // Verify the IP address allocated for the endpoint belongs to the container network 226 epOptions := make(map[string]interface{}) 227 te := newTestEndpoint(cnw, 10) 228 err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions) 229 if err != nil { 230 t.Fatalf("Failed to create an endpoint : %s", err.Error()) 231 } 232 233 if !cnw.Contains(te.Interface().Address().IP) { 234 t.Fatalf("endpoint got assigned address outside of container network(%s): %s", cnw.String(), te.Interface().Address()) 235 } 236 } 237 238 func TestCreateNoConfig(t *testing.T) { 239 defer testutils.SetupTestOSContext(t)() 240 d := newDriver() 241 242 netconfig := &networkConfiguration{BridgeName: DefaultBridgeName} 243 genericOption := make(map[string]interface{}) 244 genericOption[netlabel.GenericData] = netconfig 245 246 if err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil); err != nil { 247 t.Fatalf("Failed to create bridge: %v", err) 248 } 249 } 250 251 func TestCreateFullOptionsLabels(t *testing.T) { 252 defer testutils.SetupTestOSContext(t)() 253 d := newDriver() 254 255 config := &configuration{ 256 EnableIPForwarding: true, 257 } 258 genericOption := make(map[string]interface{}) 259 genericOption[netlabel.GenericData] = config 260 261 if err := d.configure(genericOption); err != nil { 262 t.Fatalf("Failed to setup driver config: %v", err) 263 } 264 265 bndIPs := "127.0.0.1" 266 testHostIP := "1.2.3.4" 267 nwV6s := "2001:db8:2600:2700:2800::/80" 268 gwV6s := "2001:db8:2600:2700:2800::25/80" 269 nwV6, _ := types.ParseCIDR(nwV6s) 270 gwV6, _ := types.ParseCIDR(gwV6s) 271 272 labels := map[string]string{ 273 BridgeName: DefaultBridgeName, 274 DefaultBridge: "true", 275 EnableICC: "true", 276 EnableIPMasquerade: "true", 277 DefaultBindingIP: bndIPs, 278 netlabel.HostIP: testHostIP, 279 } 280 281 netOption := make(map[string]interface{}) 282 netOption[netlabel.EnableIPv6] = true 283 netOption[netlabel.GenericData] = labels 284 285 ipdList := getIPv4Data(t, "") 286 ipd6List := []driverapi.IPAMData{ 287 { 288 Pool: nwV6, 289 AuxAddresses: map[string]*net.IPNet{ 290 DefaultGatewayV6AuxKey: gwV6, 291 }, 292 }, 293 } 294 295 err := d.CreateNetwork("dummy", netOption, nil, ipdList, ipd6List) 296 if err != nil { 297 t.Fatalf("Failed to create bridge: %v", err) 298 } 299 300 nw, ok := d.networks["dummy"] 301 if !ok { 302 t.Fatal("Cannot find dummy network in bridge driver") 303 } 304 305 if nw.config.BridgeName != DefaultBridgeName { 306 t.Fatal("incongruent name in bridge network") 307 } 308 309 if !nw.config.EnableIPv6 { 310 t.Fatal("incongruent EnableIPv6 in bridge network") 311 } 312 313 if !nw.config.EnableICC { 314 t.Fatal("incongruent EnableICC in bridge network") 315 } 316 317 if !nw.config.EnableIPMasquerade { 318 t.Fatal("incongruent EnableIPMasquerade in bridge network") 319 } 320 321 bndIP := net.ParseIP(bndIPs) 322 if !bndIP.Equal(nw.config.DefaultBindingIP) { 323 t.Fatalf("Unexpected: %v", nw.config.DefaultBindingIP) 324 } 325 326 hostIP := net.ParseIP(testHostIP) 327 if !hostIP.Equal(nw.config.HostIP) { 328 t.Fatalf("Unexpected: %v", nw.config.HostIP) 329 } 330 331 if !types.CompareIPNet(nw.config.AddressIPv6, nwV6) { 332 t.Fatalf("Unexpected: %v", nw.config.AddressIPv6) 333 } 334 335 if !gwV6.IP.Equal(nw.config.DefaultGatewayIPv6) { 336 t.Fatalf("Unexpected: %v", nw.config.DefaultGatewayIPv6) 337 } 338 339 // In short here we are testing --fixed-cidr-v6 daemon option 340 // plus --mac-address run option 341 mac, _ := net.ParseMAC("aa:bb:cc:dd:ee:ff") 342 epOptions := map[string]interface{}{netlabel.MacAddress: mac} 343 te := newTestEndpoint(ipdList[0].Pool, 20) 344 err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions) 345 if err != nil { 346 t.Fatal(err) 347 } 348 349 if !nwV6.Contains(te.Interface().AddressIPv6().IP) { 350 t.Fatalf("endpoint got assigned address outside of container network(%s): %s", nwV6.String(), te.Interface().AddressIPv6()) 351 } 352 if te.Interface().AddressIPv6().IP.String() != "2001:db8:2600:2700:2800:aabb:ccdd:eeff" { 353 t.Fatalf("Unexpected endpoint IPv6 address: %v", te.Interface().AddressIPv6().IP) 354 } 355 } 356 357 func TestCreate(t *testing.T) { 358 defer testutils.SetupTestOSContext(t)() 359 360 d := newDriver() 361 362 if err := d.configure(nil); err != nil { 363 t.Fatalf("Failed to setup driver config: %v", err) 364 } 365 366 netconfig := &networkConfiguration{BridgeName: DefaultBridgeName} 367 genericOption := make(map[string]interface{}) 368 genericOption[netlabel.GenericData] = netconfig 369 370 if err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil); err != nil { 371 t.Fatalf("Failed to create bridge: %v", err) 372 } 373 374 err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil) 375 if err == nil { 376 t.Fatal("Expected bridge driver to refuse creation of second network with default name") 377 } 378 if _, ok := err.(types.ForbiddenError); !ok { 379 t.Fatal("Creation of second network with default name failed with unexpected error type") 380 } 381 } 382 383 func TestCreateFail(t *testing.T) { 384 defer testutils.SetupTestOSContext(t)() 385 386 d := newDriver() 387 388 if err := d.configure(nil); err != nil { 389 t.Fatalf("Failed to setup driver config: %v", err) 390 } 391 392 netconfig := &networkConfiguration{BridgeName: "dummy0", DefaultBridge: true} 393 genericOption := make(map[string]interface{}) 394 genericOption[netlabel.GenericData] = netconfig 395 396 if err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil); err == nil { 397 t.Fatal("Bridge creation was expected to fail") 398 } 399 } 400 401 func TestCreateMultipleNetworks(t *testing.T) { 402 defer testutils.SetupTestOSContext(t)() 403 404 d := newDriver() 405 406 config := &configuration{ 407 EnableIPTables: true, 408 } 409 genericOption := make(map[string]interface{}) 410 genericOption[netlabel.GenericData] = config 411 412 if err := d.configure(genericOption); err != nil { 413 t.Fatalf("Failed to setup driver config: %v", err) 414 } 415 416 config1 := &networkConfiguration{BridgeName: "net_test_1"} 417 genericOption = make(map[string]interface{}) 418 genericOption[netlabel.GenericData] = config1 419 if err := d.CreateNetwork("1", genericOption, nil, getIPv4Data(t, ""), nil); err != nil { 420 t.Fatalf("Failed to create bridge: %v", err) 421 } 422 423 verifyV4INCEntries(d.networks, t) 424 425 config2 := &networkConfiguration{BridgeName: "net_test_2"} 426 genericOption[netlabel.GenericData] = config2 427 if err := d.CreateNetwork("2", genericOption, nil, getIPv4Data(t, ""), nil); err != nil { 428 t.Fatalf("Failed to create bridge: %v", err) 429 } 430 431 verifyV4INCEntries(d.networks, t) 432 433 config3 := &networkConfiguration{BridgeName: "net_test_3"} 434 genericOption[netlabel.GenericData] = config3 435 if err := d.CreateNetwork("3", genericOption, nil, getIPv4Data(t, ""), nil); err != nil { 436 t.Fatalf("Failed to create bridge: %v", err) 437 } 438 439 verifyV4INCEntries(d.networks, t) 440 441 config4 := &networkConfiguration{BridgeName: "net_test_4"} 442 genericOption[netlabel.GenericData] = config4 443 if err := d.CreateNetwork("4", genericOption, nil, getIPv4Data(t, ""), nil); err != nil { 444 t.Fatalf("Failed to create bridge: %v", err) 445 } 446 447 verifyV4INCEntries(d.networks, t) 448 449 if err := d.DeleteNetwork("1"); err != nil { 450 t.Log(err) 451 } 452 verifyV4INCEntries(d.networks, t) 453 454 if err := d.DeleteNetwork("2"); err != nil { 455 t.Log(err) 456 } 457 verifyV4INCEntries(d.networks, t) 458 459 if err := d.DeleteNetwork("3"); err != nil { 460 t.Log(err) 461 } 462 verifyV4INCEntries(d.networks, t) 463 464 if err := d.DeleteNetwork("4"); err != nil { 465 t.Log(err) 466 } 467 verifyV4INCEntries(d.networks, t) 468 } 469 470 // Verify the network isolation rules are installed for each network 471 func verifyV4INCEntries(networks map[string]*bridgeNetwork, t *testing.T) { 472 iptable := iptables.GetIptable(iptables.IPv4) 473 out1, err := iptable.Raw("-S", IsolationChain1) 474 if err != nil { 475 t.Fatal(err) 476 } 477 out2, err := iptable.Raw("-S", IsolationChain2) 478 if err != nil { 479 t.Fatal(err) 480 } 481 482 for _, n := range networks { 483 re := regexp.MustCompile(fmt.Sprintf("-i %s ! -o %s -j %s", n.config.BridgeName, n.config.BridgeName, IsolationChain2)) 484 matches := re.FindAllString(string(out1[:]), -1) 485 if len(matches) != 1 { 486 t.Fatalf("Cannot find expected inter-network isolation rules in IP Tables for network %s:\n%s.", n.id, string(out1[:])) 487 } 488 re = regexp.MustCompile(fmt.Sprintf("-o %s -j DROP", n.config.BridgeName)) 489 matches = re.FindAllString(string(out2[:]), -1) 490 if len(matches) != 1 { 491 t.Fatalf("Cannot find expected inter-network isolation rules in IP Tables for network %s:\n%s.", n.id, string(out2[:])) 492 } 493 } 494 } 495 496 type testInterface struct { 497 mac net.HardwareAddr 498 addr *net.IPNet 499 addrv6 *net.IPNet 500 srcName string 501 dstName string 502 } 503 504 type testEndpoint struct { 505 iface *testInterface 506 gw net.IP 507 gw6 net.IP 508 routes []types.StaticRoute 509 } 510 511 func newTestEndpoint(nw *net.IPNet, ordinal byte) *testEndpoint { 512 addr := types.GetIPNetCopy(nw) 513 addr.IP[len(addr.IP)-1] = ordinal 514 return &testEndpoint{iface: &testInterface{addr: addr}} 515 } 516 517 func (te *testEndpoint) Interface() driverapi.InterfaceInfo { 518 if te.iface != nil { 519 return te.iface 520 } 521 522 return nil 523 } 524 525 func (i *testInterface) MacAddress() net.HardwareAddr { 526 return i.mac 527 } 528 529 func (i *testInterface) Address() *net.IPNet { 530 return i.addr 531 } 532 533 func (i *testInterface) AddressIPv6() *net.IPNet { 534 return i.addrv6 535 } 536 537 func (i *testInterface) SetMacAddress(mac net.HardwareAddr) error { 538 if i.mac != nil { 539 return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", i.mac, mac) 540 } 541 if mac == nil { 542 return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface") 543 } 544 i.mac = types.GetMacCopy(mac) 545 return nil 546 } 547 548 func (i *testInterface) SetIPAddress(address *net.IPNet) error { 549 if address.IP == nil { 550 return types.BadRequestErrorf("tried to set nil IP address to endpoint interface") 551 } 552 if address.IP.To4() == nil { 553 return setAddress(&i.addrv6, address) 554 } 555 return setAddress(&i.addr, address) 556 } 557 558 func setAddress(ifaceAddr **net.IPNet, address *net.IPNet) error { 559 if *ifaceAddr != nil { 560 return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with (%s).", *ifaceAddr, address) 561 } 562 *ifaceAddr = types.GetIPNetCopy(address) 563 return nil 564 } 565 566 func (i *testInterface) SetNames(srcName string, dstName string) error { 567 i.srcName = srcName 568 i.dstName = dstName 569 return nil 570 } 571 572 func (te *testEndpoint) InterfaceName() driverapi.InterfaceNameInfo { 573 if te.iface != nil { 574 return te.iface 575 } 576 577 return nil 578 } 579 580 func (te *testEndpoint) SetGateway(gw net.IP) error { 581 te.gw = gw 582 return nil 583 } 584 585 func (te *testEndpoint) SetGatewayIPv6(gw6 net.IP) error { 586 te.gw6 = gw6 587 return nil 588 } 589 590 func (te *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error { 591 te.routes = append(te.routes, types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop}) 592 return nil 593 } 594 595 func (te *testEndpoint) AddTableEntry(tableName string, key string, value []byte) error { 596 return nil 597 } 598 599 func (te *testEndpoint) DisableGatewayService() {} 600 601 func TestQueryEndpointInfo(t *testing.T) { 602 testQueryEndpointInfo(t, true) 603 } 604 605 func TestQueryEndpointInfoHairpin(t *testing.T) { 606 testQueryEndpointInfo(t, false) 607 } 608 609 func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { 610 defer testutils.SetupTestOSContext(t)() 611 d := newDriver() 612 d.portAllocator = portallocator.NewInstance() 613 614 config := &configuration{ 615 EnableIPTables: true, 616 EnableUserlandProxy: ulPxyEnabled, 617 } 618 genericOption := make(map[string]interface{}) 619 genericOption[netlabel.GenericData] = config 620 621 if err := d.configure(genericOption); err != nil { 622 t.Fatalf("Failed to setup driver config: %v", err) 623 } 624 625 netconfig := &networkConfiguration{ 626 BridgeName: DefaultBridgeName, 627 EnableICC: false, 628 } 629 genericOption = make(map[string]interface{}) 630 genericOption[netlabel.GenericData] = netconfig 631 632 ipdList := getIPv4Data(t, "") 633 err := d.CreateNetwork("net1", genericOption, nil, ipdList, nil) 634 if err != nil { 635 t.Fatalf("Failed to create bridge: %v", err) 636 } 637 638 sbOptions := make(map[string]interface{}) 639 sbOptions[netlabel.PortMap] = getPortMapping() 640 641 te := newTestEndpoint(ipdList[0].Pool, 11) 642 err = d.CreateEndpoint("net1", "ep1", te.Interface(), nil) 643 if err != nil { 644 t.Fatalf("Failed to create an endpoint : %s", err.Error()) 645 } 646 647 err = d.Join("net1", "ep1", "sbox", te, sbOptions) 648 if err != nil { 649 t.Fatalf("Failed to join the endpoint: %v", err) 650 } 651 652 err = d.ProgramExternalConnectivity("net1", "ep1", sbOptions) 653 if err != nil { 654 t.Fatalf("Failed to program external connectivity: %v", err) 655 } 656 657 network, ok := d.networks["net1"] 658 if !ok { 659 t.Fatalf("Cannot find network %s inside driver", "net1") 660 } 661 ep := network.endpoints["ep1"] 662 data, err := d.EndpointOperInfo(network.id, ep.id) 663 if err != nil { 664 t.Fatalf("Failed to ask for endpoint operational data: %v", err) 665 } 666 pmd, ok := data[netlabel.PortMap] 667 if !ok { 668 t.Fatal("Endpoint operational data does not contain port mapping data") 669 } 670 pm, ok := pmd.([]types.PortBinding) 671 if !ok { 672 t.Fatal("Unexpected format for port mapping in endpoint operational data") 673 } 674 if len(ep.portMapping) != len(pm) { 675 t.Fatal("Incomplete data for port mapping in endpoint operational data") 676 } 677 for i, pb := range ep.portMapping { 678 if !pb.Equal(&pm[i]) { 679 t.Fatal("Unexpected data for port mapping in endpoint operational data") 680 } 681 } 682 683 err = d.RevokeExternalConnectivity("net1", "ep1") 684 if err != nil { 685 t.Fatal(err) 686 } 687 688 // release host mapped ports 689 err = d.Leave("net1", "ep1") 690 if err != nil { 691 t.Fatal(err) 692 } 693 } 694 695 func getExposedPorts() []types.TransportPort { 696 return []types.TransportPort{ 697 {Proto: types.TCP, Port: uint16(5000)}, 698 {Proto: types.UDP, Port: uint16(400)}, 699 {Proto: types.TCP, Port: uint16(600)}, 700 } 701 } 702 703 func getPortMapping() []types.PortBinding { 704 return []types.PortBinding{ 705 {Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)}, 706 {Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)}, 707 {Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)}, 708 } 709 } 710 711 func TestLinkContainers(t *testing.T) { 712 defer testutils.SetupTestOSContext(t)() 713 714 d := newDriver() 715 iptable := iptables.GetIptable(iptables.IPv4) 716 717 config := &configuration{ 718 EnableIPTables: true, 719 } 720 genericOption := make(map[string]interface{}) 721 genericOption[netlabel.GenericData] = config 722 723 if err := d.configure(genericOption); err != nil { 724 t.Fatalf("Failed to setup driver config: %v", err) 725 } 726 727 netconfig := &networkConfiguration{ 728 BridgeName: DefaultBridgeName, 729 EnableICC: false, 730 } 731 genericOption = make(map[string]interface{}) 732 genericOption[netlabel.GenericData] = netconfig 733 734 ipdList := getIPv4Data(t, "") 735 err := d.CreateNetwork("net1", genericOption, nil, ipdList, nil) 736 if err != nil { 737 t.Fatalf("Failed to create bridge: %v", err) 738 } 739 740 te1 := newTestEndpoint(ipdList[0].Pool, 11) 741 err = d.CreateEndpoint("net1", "ep1", te1.Interface(), nil) 742 if err != nil { 743 t.Fatalf("Failed to create an endpoint : %s", err.Error()) 744 } 745 746 exposedPorts := getExposedPorts() 747 sbOptions := make(map[string]interface{}) 748 sbOptions[netlabel.ExposedPorts] = exposedPorts 749 750 err = d.Join("net1", "ep1", "sbox", te1, sbOptions) 751 if err != nil { 752 t.Fatalf("Failed to join the endpoint: %v", err) 753 } 754 755 err = d.ProgramExternalConnectivity("net1", "ep1", sbOptions) 756 if err != nil { 757 t.Fatalf("Failed to program external connectivity: %v", err) 758 } 759 760 addr1 := te1.iface.addr 761 if addr1.IP.To4() == nil { 762 t.Fatal("No Ipv4 address assigned to the endpoint: ep1") 763 } 764 765 te2 := newTestEndpoint(ipdList[0].Pool, 22) 766 err = d.CreateEndpoint("net1", "ep2", te2.Interface(), nil) 767 if err != nil { 768 t.Fatalf("Failed to create an endpoint : %s", err.Error()) 769 } 770 771 addr2 := te2.iface.addr 772 if addr2.IP.To4() == nil { 773 t.Fatal("No Ipv4 address assigned to the endpoint: ep2") 774 } 775 776 sbOptions = make(map[string]interface{}) 777 sbOptions[netlabel.GenericData] = options.Generic{ 778 "ChildEndpoints": []string{"ep1"}, 779 } 780 781 err = d.Join("net1", "ep2", "", te2, sbOptions) 782 if err != nil { 783 t.Fatal("Failed to link ep1 and ep2") 784 } 785 786 err = d.ProgramExternalConnectivity("net1", "ep2", sbOptions) 787 if err != nil { 788 t.Fatalf("Failed to program external connectivity: %v", err) 789 } 790 791 out, _ := iptable.Raw("-L", DockerChain) 792 for _, pm := range exposedPorts { 793 regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port) 794 re := regexp.MustCompile(regex) 795 matches := re.FindAllString(string(out[:]), -1) 796 if len(matches) != 1 { 797 t.Fatalf("IP Tables programming failed %s", string(out[:])) 798 } 799 800 regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port) 801 matched, _ := regexp.MatchString(regex, string(out[:])) 802 if !matched { 803 t.Fatalf("IP Tables programming failed %s", string(out[:])) 804 } 805 } 806 807 err = d.RevokeExternalConnectivity("net1", "ep2") 808 if err != nil { 809 t.Fatalf("Failed to revoke external connectivity: %v", err) 810 } 811 812 err = d.Leave("net1", "ep2") 813 if err != nil { 814 t.Fatal("Failed to unlink ep1 and ep2") 815 } 816 817 out, _ = iptable.Raw("-L", DockerChain) 818 for _, pm := range exposedPorts { 819 regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port) 820 re := regexp.MustCompile(regex) 821 matches := re.FindAllString(string(out[:]), -1) 822 if len(matches) != 0 { 823 t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:])) 824 } 825 826 regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port) 827 matched, _ := regexp.MatchString(regex, string(out[:])) 828 if matched { 829 t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:])) 830 } 831 } 832 833 // Error condition test with an invalid endpoint-id "ep4" 834 sbOptions = make(map[string]interface{}) 835 sbOptions[netlabel.GenericData] = options.Generic{ 836 "ChildEndpoints": []string{"ep1", "ep4"}, 837 } 838 839 err = d.Join("net1", "ep2", "", te2, sbOptions) 840 if err != nil { 841 t.Fatal(err) 842 } 843 err = d.ProgramExternalConnectivity("net1", "ep2", sbOptions) 844 if err != nil { 845 out, _ = iptable.Raw("-L", DockerChain) 846 for _, pm := range exposedPorts { 847 regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port) 848 re := regexp.MustCompile(regex) 849 matches := re.FindAllString(string(out[:]), -1) 850 if len(matches) != 0 { 851 t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:])) 852 } 853 854 regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port) 855 matched, _ := regexp.MatchString(regex, string(out[:])) 856 if matched { 857 t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:])) 858 } 859 } 860 } else { 861 t.Fatal("Expected Join to fail given link conditions are not satisfied") 862 } 863 } 864 865 func TestValidateConfig(t *testing.T) { 866 defer testutils.SetupTestOSContext(t)() 867 868 // Test mtu 869 c := networkConfiguration{Mtu: -2} 870 err := c.Validate() 871 if err == nil { 872 t.Fatal("Failed to detect invalid MTU number") 873 } 874 875 c.Mtu = 9000 876 err = c.Validate() 877 if err != nil { 878 t.Fatal("unexpected validation error on MTU number") 879 } 880 881 // Bridge network 882 _, network, _ := net.ParseCIDR("172.28.0.0/16") 883 c = networkConfiguration{ 884 AddressIPv4: network, 885 } 886 887 err = c.Validate() 888 if err != nil { 889 t.Fatal(err) 890 } 891 892 // Test v4 gw 893 c.DefaultGatewayIPv4 = net.ParseIP("172.27.30.234") 894 err = c.Validate() 895 if err == nil { 896 t.Fatal("Failed to detect invalid default gateway") 897 } 898 899 c.DefaultGatewayIPv4 = net.ParseIP("172.28.30.234") 900 err = c.Validate() 901 if err != nil { 902 t.Fatal("Unexpected validation error on default gateway") 903 } 904 905 // Test v6 gw 906 _, v6nw, _ := net.ParseCIDR("2001:db8:ae:b004::/64") 907 c = networkConfiguration{ 908 EnableIPv6: true, 909 AddressIPv6: v6nw, 910 DefaultGatewayIPv6: net.ParseIP("2001:db8:ac:b004::bad:a55"), 911 } 912 err = c.Validate() 913 if err == nil { 914 t.Fatal("Failed to detect invalid v6 default gateway") 915 } 916 917 c.DefaultGatewayIPv6 = net.ParseIP("2001:db8:ae:b004::bad:a55") 918 err = c.Validate() 919 if err != nil { 920 t.Fatal("Unexpected validation error on v6 default gateway") 921 } 922 923 c.AddressIPv6 = nil 924 err = c.Validate() 925 if err == nil { 926 t.Fatal("Failed to detect invalid v6 default gateway") 927 } 928 929 c.AddressIPv6 = nil 930 err = c.Validate() 931 if err == nil { 932 t.Fatal("Failed to detect invalid v6 default gateway") 933 } 934 } 935 936 func TestSetDefaultGw(t *testing.T) { 937 defer testutils.SetupTestOSContext(t)() 938 939 d := newDriver() 940 941 if err := d.configure(nil); err != nil { 942 t.Fatalf("Failed to setup driver config: %v", err) 943 } 944 945 _, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80") 946 947 ipdList := getIPv4Data(t, "") 948 gw4 := types.GetIPCopy(ipdList[0].Pool.IP).To4() 949 gw4[3] = 254 950 gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254") 951 952 config := &networkConfiguration{ 953 BridgeName: DefaultBridgeName, 954 AddressIPv6: subnetv6, 955 DefaultGatewayIPv4: gw4, 956 DefaultGatewayIPv6: gw6, 957 } 958 959 genericOption := make(map[string]interface{}) 960 genericOption[netlabel.EnableIPv6] = true 961 genericOption[netlabel.GenericData] = config 962 963 err := d.CreateNetwork("dummy", genericOption, nil, ipdList, nil) 964 if err != nil { 965 t.Fatalf("Failed to create bridge: %v", err) 966 } 967 968 te := newTestEndpoint(ipdList[0].Pool, 10) 969 err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil) 970 if err != nil { 971 t.Fatalf("Failed to create endpoint: %v", err) 972 } 973 974 err = d.Join("dummy", "ep", "sbox", te, nil) 975 if err != nil { 976 t.Fatalf("Failed to join endpoint: %v", err) 977 } 978 979 if !gw4.Equal(te.gw) { 980 t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw4, te.gw) 981 } 982 983 if !gw6.Equal(te.gw6) { 984 t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw6, te.gw6) 985 } 986 } 987 988 func TestCleanupIptableRules(t *testing.T) { 989 defer testutils.SetupTestOSContext(t)() 990 bridgeChain := []iptables.ChainInfo{ 991 {Name: DockerChain, Table: iptables.Nat}, 992 {Name: DockerChain, Table: iptables.Filter}, 993 {Name: IsolationChain1, Table: iptables.Filter}, 994 } 995 996 ipVersions := []iptables.IPVersion{iptables.IPv4, iptables.IPv6} 997 998 for _, version := range ipVersions { 999 if _, _, _, _, err := setupIPChains(configuration{EnableIPTables: true}, version); err != nil { 1000 t.Fatalf("Error setting up ip chains for %s: %v", version, err) 1001 } 1002 1003 iptable := iptables.GetIptable(version) 1004 for _, chainInfo := range bridgeChain { 1005 if !iptable.ExistChain(chainInfo.Name, chainInfo.Table) { 1006 t.Fatalf("iptables version %s chain %s of %s table should have been created", version, chainInfo.Name, chainInfo.Table) 1007 } 1008 } 1009 removeIPChains(version) 1010 for _, chainInfo := range bridgeChain { 1011 if iptable.ExistChain(chainInfo.Name, chainInfo.Table) { 1012 t.Fatalf("iptables version %s chain %s of %s table should have been deleted", version, chainInfo.Name, chainInfo.Table) 1013 } 1014 } 1015 } 1016 } 1017 1018 func TestCreateWithExistingBridge(t *testing.T) { 1019 defer testutils.SetupTestOSContext(t)() 1020 d := newDriver() 1021 1022 if err := d.configure(nil); err != nil { 1023 t.Fatalf("Failed to setup driver config: %v", err) 1024 } 1025 1026 brName := "br111" 1027 br := &netlink.Bridge{ 1028 LinkAttrs: netlink.LinkAttrs{ 1029 Name: brName, 1030 }, 1031 } 1032 if err := netlink.LinkAdd(br); err != nil { 1033 t.Fatalf("Failed to create bridge interface: %v", err) 1034 } 1035 defer netlink.LinkDel(br) 1036 if err := netlink.LinkSetUp(br); err != nil { 1037 t.Fatalf("Failed to set bridge interface up: %v", err) 1038 } 1039 1040 ip := net.IP{192, 168, 122, 1} 1041 addr := &netlink.Addr{IPNet: &net.IPNet{ 1042 IP: ip, 1043 Mask: net.IPv4Mask(255, 255, 255, 0), 1044 }} 1045 if err := netlink.AddrAdd(br, addr); err != nil { 1046 t.Fatalf("Failed to add IP address to bridge: %v", err) 1047 } 1048 1049 netconfig := &networkConfiguration{BridgeName: brName} 1050 genericOption := make(map[string]interface{}) 1051 genericOption[netlabel.GenericData] = netconfig 1052 1053 ipv4Data := []driverapi.IPAMData{{ 1054 AddressSpace: "full", 1055 Pool: types.GetIPNetCopy(addr.IPNet), 1056 Gateway: types.GetIPNetCopy(addr.IPNet), 1057 }} 1058 // Set network gateway to X.X.X.1 1059 ipv4Data[0].Gateway.IP[len(ipv4Data[0].Gateway.IP)-1] = 1 1060 1061 if err := d.CreateNetwork(brName, genericOption, nil, ipv4Data, nil); err != nil { 1062 t.Fatalf("Failed to create bridge network: %v", err) 1063 } 1064 1065 nw, err := d.getNetwork(brName) 1066 if err != nil { 1067 t.Fatalf("Failed to getNetwork(%s): %v", brName, err) 1068 } 1069 1070 addrs4, _, err := nw.bridge.addresses() 1071 if err != nil { 1072 t.Fatalf("Failed to get the bridge network's address: %v", err) 1073 } 1074 1075 if !addrs4[0].IP.Equal(ip) { 1076 t.Fatal("Creating bridge network with existing bridge interface unexpectedly modified the IP address of the bridge") 1077 } 1078 1079 if err := d.DeleteNetwork(brName); err != nil { 1080 t.Fatalf("Failed to delete network %s: %v", brName, err) 1081 } 1082 1083 if _, err := netlink.LinkByName(brName); err != nil { 1084 t.Fatal("Deleting bridge network that using existing bridge interface unexpectedly deleted the bridge interface") 1085 } 1086 } 1087 1088 func TestCreateParallel(t *testing.T) { 1089 c := testutils.SetupTestOSContextEx(t) 1090 defer c.Cleanup(t) 1091 1092 d := newDriver() 1093 d.portAllocator = portallocator.NewInstance() 1094 1095 if err := d.configure(nil); err != nil { 1096 t.Fatalf("Failed to setup driver config: %v", err) 1097 } 1098 1099 ipV4Data := getIPv4Data(t, "docker0") 1100 1101 ch := make(chan error, 100) 1102 for i := 0; i < 100; i++ { 1103 name := "net" + strconv.Itoa(i) 1104 c.Go(t, func() { 1105 config := &networkConfiguration{BridgeName: name} 1106 genericOption := make(map[string]interface{}) 1107 genericOption[netlabel.GenericData] = config 1108 if err := d.CreateNetwork(name, genericOption, nil, ipV4Data, nil); err != nil { 1109 ch <- fmt.Errorf("failed to create %s", name) 1110 return 1111 } 1112 if err := d.CreateNetwork(name, genericOption, nil, ipV4Data, nil); err == nil { 1113 ch <- fmt.Errorf("failed was able to create overlap %s", name) 1114 return 1115 } 1116 ch <- nil 1117 }) 1118 } 1119 // wait for the go routines 1120 var success int 1121 for i := 0; i < 100; i++ { 1122 val := <-ch 1123 if val == nil { 1124 success++ 1125 } 1126 } 1127 if success != 1 { 1128 t.Fatalf("Success should be 1 instead: %d", success) 1129 } 1130 }