| //go:build linux |
| // +build linux |
| |
| package bridge |
| |
| import ( |
| "os" |
| "testing" |
| |
| "github.com/docker/docker/libnetwork/netlabel" |
| "github.com/docker/docker/libnetwork/ns" |
| "github.com/docker/docker/libnetwork/testutils" |
| "github.com/docker/docker/libnetwork/types" |
| "github.com/docker/docker/pkg/reexec" |
| ) |
| |
| func TestMain(m *testing.M) { |
| if reexec.Init() { |
| return |
| } |
| os.Exit(m.Run()) |
| } |
| |
| func TestPortMappingConfig(t *testing.T) { |
| defer testutils.SetupTestOSContext(t)() |
| d := newDriver() |
| |
| config := &configuration{ |
| EnableIPTables: true, |
| } |
| genericOption := make(map[string]interface{}) |
| genericOption[netlabel.GenericData] = config |
| |
| if err := d.configure(genericOption); err != nil { |
| t.Fatalf("Failed to setup driver config: %v", err) |
| } |
| |
| binding1 := types.PortBinding{Proto: types.UDP, Port: uint16(400), HostPort: uint16(54000)} |
| binding2 := types.PortBinding{Proto: types.TCP, Port: uint16(500), HostPort: uint16(65000)} |
| binding3 := types.PortBinding{Proto: types.SCTP, Port: uint16(300), HostPort: uint16(65000)} |
| portBindings := []types.PortBinding{binding1, binding2, binding3} |
| |
| sbOptions := make(map[string]interface{}) |
| sbOptions[netlabel.PortMap] = portBindings |
| |
| netConfig := &networkConfiguration{ |
| BridgeName: DefaultBridgeName, |
| } |
| netOptions := make(map[string]interface{}) |
| netOptions[netlabel.GenericData] = netConfig |
| |
| ipdList := getIPv4Data(t, "") |
| err := d.CreateNetwork("dummy", netOptions, nil, ipdList, nil) |
| if err != nil { |
| t.Fatalf("Failed to create bridge: %v", err) |
| } |
| |
| te := newTestEndpoint(ipdList[0].Pool, 11) |
| err = d.CreateEndpoint("dummy", "ep1", te.Interface(), nil) |
| if err != nil { |
| t.Fatalf("Failed to create the endpoint: %s", err.Error()) |
| } |
| |
| if err = d.Join("dummy", "ep1", "sbox", te, sbOptions); err != nil { |
| t.Fatalf("Failed to join the endpoint: %v", err) |
| } |
| |
| if err = d.ProgramExternalConnectivity("dummy", "ep1", sbOptions); err != nil { |
| t.Fatalf("Failed to program external connectivity: %v", err) |
| } |
| |
| network, ok := d.networks["dummy"] |
| if !ok { |
| t.Fatalf("Cannot find network %s inside driver", "dummy") |
| } |
| ep := network.endpoints["ep1"] |
| if len(ep.portMapping) != 3 { |
| t.Fatalf("Failed to store the port bindings into the sandbox info. Found: %v", ep.portMapping) |
| } |
| if ep.portMapping[0].Proto != binding1.Proto || ep.portMapping[0].Port != binding1.Port || |
| ep.portMapping[1].Proto != binding2.Proto || ep.portMapping[1].Port != binding2.Port || |
| ep.portMapping[2].Proto != binding3.Proto || ep.portMapping[2].Port != binding3.Port { |
| t.Fatal("bridgeEndpoint has incorrect port mapping values") |
| } |
| if ep.portMapping[0].HostIP == nil || ep.portMapping[0].HostPort == 0 || |
| ep.portMapping[1].HostIP == nil || ep.portMapping[1].HostPort == 0 || |
| ep.portMapping[2].HostIP == nil || ep.portMapping[2].HostPort == 0 { |
| t.Fatal("operational port mapping data not found on bridgeEndpoint") |
| } |
| |
| // release host mapped ports |
| err = d.Leave("dummy", "ep1") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| err = d.RevokeExternalConnectivity("dummy", "ep1") |
| if err != nil { |
| t.Fatal(err) |
| } |
| } |
| |
| func TestPortMappingV6Config(t *testing.T) { |
| defer testutils.SetupTestOSContext(t)() |
| if err := loopbackUp(); err != nil { |
| t.Fatalf("Could not bring loopback iface up: %v", err) |
| } |
| |
| d := newDriver() |
| |
| config := &configuration{ |
| EnableIPTables: true, |
| EnableIP6Tables: true, |
| } |
| genericOption := make(map[string]interface{}) |
| genericOption[netlabel.GenericData] = config |
| |
| if err := d.configure(genericOption); err != nil { |
| t.Fatalf("Failed to setup driver config: %v", err) |
| } |
| |
| portBindings := []types.PortBinding{ |
| {Proto: types.UDP, Port: uint16(400), HostPort: uint16(54000)}, |
| {Proto: types.TCP, Port: uint16(500), HostPort: uint16(65000)}, |
| {Proto: types.SCTP, Port: uint16(500), HostPort: uint16(65000)}, |
| } |
| |
| sbOptions := make(map[string]interface{}) |
| sbOptions[netlabel.PortMap] = portBindings |
| netConfig := &networkConfiguration{ |
| BridgeName: DefaultBridgeName, |
| EnableIPv6: true, |
| } |
| netOptions := make(map[string]interface{}) |
| netOptions[netlabel.GenericData] = netConfig |
| |
| ipdList := getIPv4Data(t, "") |
| err := d.CreateNetwork("dummy", netOptions, nil, ipdList, nil) |
| if err != nil { |
| t.Fatalf("Failed to create bridge: %v", err) |
| } |
| |
| te := newTestEndpoint(ipdList[0].Pool, 11) |
| err = d.CreateEndpoint("dummy", "ep1", te.Interface(), nil) |
| if err != nil { |
| t.Fatalf("Failed to create the endpoint: %s", err.Error()) |
| } |
| |
| if err = d.Join("dummy", "ep1", "sbox", te, sbOptions); err != nil { |
| t.Fatalf("Failed to join the endpoint: %v", err) |
| } |
| |
| if err = d.ProgramExternalConnectivity("dummy", "ep1", sbOptions); err != nil { |
| t.Fatalf("Failed to program external connectivity: %v", err) |
| } |
| |
| network, ok := d.networks["dummy"] |
| if !ok { |
| t.Fatalf("Cannot find network %s inside driver", "dummy") |
| } |
| ep := network.endpoints["ep1"] |
| if len(ep.portMapping) != 6 { |
| t.Fatalf("Failed to store the port bindings into the sandbox info. Found: %v", ep.portMapping) |
| } |
| |
| // release host mapped ports |
| err = d.Leave("dummy", "ep1") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| err = d.RevokeExternalConnectivity("dummy", "ep1") |
| if err != nil { |
| t.Fatal(err) |
| } |
| } |
| |
| func loopbackUp() error { |
| nlHandle := ns.NlHandle() |
| iface, err := nlHandle.LinkByName("lo") |
| if err != nil { |
| return err |
| } |
| return nlHandle.LinkSetUp(iface) |
| } |