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