Browse code

Remove jobs from daemon/networkdriver/bridge

Signed-off-by: Tibor Vass <tibor@docker.com>

Tibor Vass authored on 2015/04/04 13:06:48
Showing 12 changed files
... ...
@@ -1,10 +1,10 @@
1 1
 package client
2 2
 
3 3
 import (
4
+	"encoding/json"
4 5
 	"fmt"
5 6
 	"strings"
6 7
 
7
-	"github.com/docker/docker/engine"
8 8
 	"github.com/docker/docker/nat"
9 9
 	flag "github.com/docker/docker/pkg/mflag"
10 10
 )
... ...
@@ -23,12 +23,13 @@ func (cli *DockerCli) CmdPort(args ...string) error {
23 23
 		return err
24 24
 	}
25 25
 
26
-	env := engine.Env{}
27
-	if err := env.Decode(stream); err != nil {
28
-		return err
26
+	var c struct {
27
+		NetworkSettings struct {
28
+			Ports nat.PortMap
29
+		}
29 30
 	}
30
-	ports := nat.PortMap{}
31
-	if err := env.GetSubEnv("NetworkSettings").GetJson("Ports", &ports); err != nil {
31
+
32
+	if err := json.NewDecoder(stream).Decode(&c); err != nil {
32 33
 		return err
33 34
 	}
34 35
 
... ...
@@ -44,7 +45,7 @@ func (cli *DockerCli) CmdPort(args ...string) error {
44 44
 			proto = parts[1]
45 45
 		}
46 46
 		natPort := port + "/" + proto
47
-		if frontends, exists := ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
47
+		if frontends, exists := c.NetworkSettings.Ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
48 48
 			for _, frontend := range frontends {
49 49
 				fmt.Fprintf(cli.out, "%s:%s\n", frontend.HostIp, frontend.HostPort)
50 50
 			}
... ...
@@ -53,7 +54,7 @@ func (cli *DockerCli) CmdPort(args ...string) error {
53 53
 		return fmt.Errorf("Error: No public port '%s' published for %s", natPort, cmd.Arg(0))
54 54
 	}
55 55
 
56
-	for from, frontends := range ports {
56
+	for from, frontends := range c.NetworkSettings.Ports {
57 57
 		for _, frontend := range frontends {
58 58
 			fmt.Fprintf(cli.out, "%s -> %s:%s\n", from, frontend.HostIp, frontend.HostPort)
59 59
 		}
... ...
@@ -6,15 +6,11 @@ import (
6 6
 	"github.com/docker/docker/api"
7 7
 	apiserver "github.com/docker/docker/api/server"
8 8
 	"github.com/docker/docker/autogen/dockerversion"
9
-	"github.com/docker/docker/daemon/networkdriver/bridge"
10 9
 	"github.com/docker/docker/engine"
11 10
 	"github.com/docker/docker/pkg/parsers/kernel"
12 11
 )
13 12
 
14 13
 func Register(eng *engine.Engine) error {
15
-	if err := daemon(eng); err != nil {
16
-		return err
17
-	}
18 14
 	if err := remote(eng); err != nil {
19 15
 		return err
20 16
 	}
... ...
@@ -33,25 +29,6 @@ func remote(eng *engine.Engine) error {
33 33
 	return eng.Register("acceptconnections", apiserver.AcceptConnections)
34 34
 }
35 35
 
36
-// daemon: a default execution and storage backend for Docker on Linux,
37
-// with the following underlying components:
38
-//
39
-// * Pluggable storage drivers including aufs, vfs, lvm and btrfs.
40
-// * Pluggable execution drivers including lxc and chroot.
41
-//
42
-// In practice `daemon` still includes most core Docker components, including:
43
-//
44
-// * The reference registry client implementation
45
-// * Image management
46
-// * The build facility
47
-// * Logging
48
-//
49
-// These components should be broken off into plugins of their own.
50
-//
51
-func daemon(eng *engine.Engine) error {
52
-	return eng.Register("init_networkdriver", bridge.InitDriver)
53
-}
54
-
55 36
 // builtins jobs independent of any subsystem
56 37
 func dockerVersion(job *engine.Job) error {
57 38
 	v := &engine.Env{}
... ...
@@ -1,9 +1,8 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
-	"net"
5
-
6 4
 	"github.com/docker/docker/daemon/networkdriver"
5
+	"github.com/docker/docker/daemon/networkdriver/bridge"
7 6
 	"github.com/docker/docker/opts"
8 7
 	flag "github.com/docker/docker/pkg/mflag"
9 8
 	"github.com/docker/docker/pkg/ulimit"
... ...
@@ -20,35 +19,27 @@ const (
20 20
 // to the docker daemon when you launch it with say: `docker -d -e lxc`
21 21
 // FIXME: separate runtime configuration from http api configuration
22 22
 type Config struct {
23
-	Pidfile                     string
24
-	Root                        string
25
-	AutoRestart                 bool
26
-	Dns                         []string
27
-	DnsSearch                   []string
28
-	EnableIPv6                  bool
29
-	EnableIptables              bool
30
-	EnableIpForward             bool
31
-	EnableIpMasq                bool
32
-	DefaultIp                   net.IP
33
-	BridgeIface                 string
34
-	BridgeIP                    string
35
-	FixedCIDR                   string
36
-	FixedCIDRv6                 string
37
-	InterContainerCommunication bool
38
-	GraphDriver                 string
39
-	GraphOptions                []string
40
-	ExecDriver                  string
41
-	Mtu                         int
42
-	SocketGroup                 string
43
-	EnableCors                  bool
44
-	CorsHeaders                 string
45
-	DisableNetwork              bool
46
-	EnableSelinuxSupport        bool
47
-	Context                     map[string][]string
48
-	TrustKeyPath                string
49
-	Labels                      []string
50
-	Ulimits                     map[string]*ulimit.Ulimit
51
-	LogConfig                   runconfig.LogConfig
23
+	Bridge bridge.Config
24
+
25
+	Pidfile              string
26
+	Root                 string
27
+	AutoRestart          bool
28
+	Dns                  []string
29
+	DnsSearch            []string
30
+	GraphDriver          string
31
+	GraphOptions         []string
32
+	ExecDriver           string
33
+	Mtu                  int
34
+	SocketGroup          string
35
+	EnableCors           bool
36
+	CorsHeaders          string
37
+	DisableNetwork       bool
38
+	EnableSelinuxSupport bool
39
+	Context              map[string][]string
40
+	TrustKeyPath         string
41
+	Labels               []string
42
+	Ulimits              map[string]*ulimit.Ulimit
43
+	LogConfig            runconfig.LogConfig
52 44
 }
53 45
 
54 46
 // InstallFlags adds command-line options to the top-level flag parser for
... ...
@@ -59,15 +50,15 @@ func (config *Config) InstallFlags() {
59 59
 	flag.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file")
60 60
 	flag.StringVar(&config.Root, []string{"g", "-graph"}, "/var/lib/docker", "Root of the Docker runtime")
61 61
 	flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
62
-	flag.BoolVar(&config.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
63
-	flag.BoolVar(&config.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
64
-	flag.BoolVar(&config.EnableIpMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
65
-	flag.BoolVar(&config.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
66
-	flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
67
-	flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
68
-	flag.StringVar(&config.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
69
-	flag.StringVar(&config.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
70
-	flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
62
+	flag.BoolVar(&config.Bridge.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
63
+	flag.BoolVar(&config.Bridge.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
64
+	flag.BoolVar(&config.Bridge.EnableIpMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
65
+	flag.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
66
+	flag.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
67
+	flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
68
+	flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
69
+	flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
70
+	flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
71 71
 	flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
72 72
 	flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Exec driver to use")
73 73
 	flag.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, "Enable selinux support")
... ...
@@ -75,7 +66,7 @@ func (config *Config) InstallFlags() {
75 75
 	flag.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", "Group for the unix socket")
76 76
 	flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header")
77 77
 	flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API")
78
-	opts.IPVar(&config.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
78
+	opts.IPVar(&config.Bridge.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
79 79
 	opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
80 80
 	// FIXME: why the inconsistency between "hosts" and "sockets"?
81 81
 	opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use")
... ...
@@ -24,6 +24,8 @@ import (
24 24
 	"github.com/docker/docker/daemon/logger"
25 25
 	"github.com/docker/docker/daemon/logger/jsonfilelog"
26 26
 	"github.com/docker/docker/daemon/logger/syslog"
27
+	"github.com/docker/docker/daemon/network"
28
+	"github.com/docker/docker/daemon/networkdriver/bridge"
27 29
 	"github.com/docker/docker/engine"
28 30
 	"github.com/docker/docker/image"
29 31
 	"github.com/docker/docker/links"
... ...
@@ -73,7 +75,7 @@ type Container struct {
73 73
 	Config  *runconfig.Config
74 74
 	ImageID string `json:"Image"`
75 75
 
76
-	NetworkSettings *NetworkSettings
76
+	NetworkSettings *network.Settings
77 77
 
78 78
 	ResolvConfPath string
79 79
 	HostnamePath   string
... ...
@@ -571,17 +573,12 @@ func (container *Container) AllocateNetwork() error {
571 571
 	}
572 572
 
573 573
 	var (
574
-		env *engine.Env
575 574
 		err error
576 575
 		eng = container.daemon.eng
577 576
 	)
578 577
 
579
-	job := eng.Job("allocate_interface", container.ID)
580
-	job.Setenv("RequestedMac", container.Config.MacAddress)
581
-	if env, err = job.Stdout.AddEnv(); err != nil {
582
-		return err
583
-	}
584
-	if err = job.Run(); err != nil {
578
+	networkSettings, err := bridge.Allocate(container.ID, container.Config.MacAddress, "", "")
579
+	if err != nil {
585 580
 		return err
586 581
 	}
587 582
 
... ...
@@ -591,12 +588,12 @@ func (container *Container) AllocateNetwork() error {
591 591
 
592 592
 	if container.Config.PortSpecs != nil {
593 593
 		if err = migratePortMappings(container.Config, container.hostConfig); err != nil {
594
-			eng.Job("release_interface", container.ID).Run()
594
+			bridge.Release(container.ID)
595 595
 			return err
596 596
 		}
597 597
 		container.Config.PortSpecs = nil
598 598
 		if err = container.WriteHostConfig(); err != nil {
599
-			eng.Job("release_interface", container.ID).Run()
599
+			bridge.Release(container.ID)
600 600
 			return err
601 601
 		}
602 602
 	}
... ...
@@ -626,23 +623,14 @@ func (container *Container) AllocateNetwork() error {
626 626
 
627 627
 	for port := range portSpecs {
628 628
 		if err = container.allocatePort(eng, port, bindings); err != nil {
629
-			eng.Job("release_interface", container.ID).Run()
629
+			bridge.Release(container.ID)
630 630
 			return err
631 631
 		}
632 632
 	}
633 633
 	container.WriteHostConfig()
634 634
 
635
-	container.NetworkSettings.Ports = bindings
636
-	container.NetworkSettings.Bridge = env.Get("Bridge")
637
-	container.NetworkSettings.IPAddress = env.Get("IP")
638
-	container.NetworkSettings.IPPrefixLen = env.GetInt("IPPrefixLen")
639
-	container.NetworkSettings.MacAddress = env.Get("MacAddress")
640
-	container.NetworkSettings.Gateway = env.Get("Gateway")
641
-	container.NetworkSettings.LinkLocalIPv6Address = env.Get("LinkLocalIPv6")
642
-	container.NetworkSettings.LinkLocalIPv6PrefixLen = 64
643
-	container.NetworkSettings.GlobalIPv6Address = env.Get("GlobalIPv6")
644
-	container.NetworkSettings.GlobalIPv6PrefixLen = env.GetInt("GlobalIPv6PrefixLen")
645
-	container.NetworkSettings.IPv6Gateway = env.Get("IPv6Gateway")
635
+	networkSettings.Ports = bindings
636
+	container.NetworkSettings = networkSettings
646 637
 
647 638
 	return nil
648 639
 }
... ...
@@ -651,12 +639,10 @@ func (container *Container) ReleaseNetwork() {
651 651
 	if container.Config.NetworkDisabled || !container.hostConfig.NetworkMode.IsPrivate() {
652 652
 		return
653 653
 	}
654
-	eng := container.daemon.eng
655 654
 
656
-	job := eng.Job("release_interface", container.ID)
657
-	job.SetenvBool("overrideShutdown", true)
658
-	job.Run()
659
-	container.NetworkSettings = &NetworkSettings{}
655
+	bridge.Release(container.ID)
656
+
657
+	container.NetworkSettings = &network.Settings{}
660 658
 }
661 659
 
662 660
 func (container *Container) isNetworkAllocated() bool {
... ...
@@ -675,10 +661,7 @@ func (container *Container) RestoreNetwork() error {
675 675
 	eng := container.daemon.eng
676 676
 
677 677
 	// Re-allocate the interface with the same IP and MAC address.
678
-	job := eng.Job("allocate_interface", container.ID)
679
-	job.Setenv("RequestedIP", container.NetworkSettings.IPAddress)
680
-	job.Setenv("RequestedMac", container.NetworkSettings.MacAddress)
681
-	if err := job.Run(); err != nil {
678
+	if _, err := bridge.Allocate(container.ID, container.NetworkSettings.MacAddress, container.NetworkSettings.IPAddress, ""); err != nil {
682 679
 		return err
683 680
 	}
684 681
 
... ...
@@ -1077,7 +1060,7 @@ func (container *Container) setupContainerDns() error {
1077 1077
 			latestResolvConf, latestHash := resolvconf.GetLastModified()
1078 1078
 
1079 1079
 			// clean container resolv.conf re: localhost nameservers and IPv6 NS (if IPv6 disabled)
1080
-			updatedResolvConf, modified := resolvconf.FilterResolvDns(latestResolvConf, container.daemon.config.EnableIPv6)
1080
+			updatedResolvConf, modified := resolvconf.FilterResolvDns(latestResolvConf, container.daemon.config.Bridge.EnableIPv6)
1081 1081
 			if modified {
1082 1082
 				// changes have occurred during resolv.conf localhost cleanup: generate an updated hash
1083 1083
 				newHash, err := utils.HashData(bytes.NewReader(updatedResolvConf))
... ...
@@ -1131,7 +1114,7 @@ func (container *Container) setupContainerDns() error {
1131 1131
 		}
1132 1132
 
1133 1133
 		// replace any localhost/127.*, and remove IPv6 nameservers if IPv6 disabled in daemon
1134
-		resolvConf, _ = resolvconf.FilterResolvDns(resolvConf, daemon.config.EnableIPv6)
1134
+		resolvConf, _ = resolvconf.FilterResolvDns(resolvConf, daemon.config.Bridge.EnableIPv6)
1135 1135
 	}
1136 1136
 	//get a sha256 hash of the resolv conf at this point so we can check
1137 1137
 	//for changes when the host resolv.conf changes (e.g. network update)
... ...
@@ -1481,24 +1464,10 @@ func (container *Container) allocatePort(eng *engine.Engine, port nat.Port, bind
1481 1481
 	}
1482 1482
 
1483 1483
 	for i := 0; i < len(binding); i++ {
1484
-		b := binding[i]
1485
-
1486
-		job := eng.Job("allocate_port", container.ID)
1487
-		job.Setenv("HostIP", b.HostIp)
1488
-		job.Setenv("HostPort", b.HostPort)
1489
-		job.Setenv("Proto", port.Proto())
1490
-		job.Setenv("ContainerPort", port.Port())
1491
-
1492
-		portEnv, err := job.Stdout.AddEnv()
1484
+		b, err := bridge.AllocatePort(container.ID, port, binding[i])
1493 1485
 		if err != nil {
1494 1486
 			return err
1495 1487
 		}
1496
-		if err := job.Run(); err != nil {
1497
-			return err
1498
-		}
1499
-		b.HostIp = portEnv.Get("HostIP")
1500
-		b.HostPort = portEnv.Get("HostPort")
1501
-
1502 1488
 		binding[i] = b
1503 1489
 	}
1504 1490
 	bindings[port] = binding
... ...
@@ -25,7 +25,8 @@ import (
25 25
 	"github.com/docker/docker/daemon/execdriver/lxc"
26 26
 	"github.com/docker/docker/daemon/graphdriver"
27 27
 	_ "github.com/docker/docker/daemon/graphdriver/vfs"
28
-	_ "github.com/docker/docker/daemon/networkdriver/bridge"
28
+	"github.com/docker/docker/daemon/network"
29
+	"github.com/docker/docker/daemon/networkdriver/bridge"
29 30
 	"github.com/docker/docker/engine"
30 31
 	"github.com/docker/docker/graph"
31 32
 	"github.com/docker/docker/image"
... ...
@@ -445,7 +446,7 @@ func (daemon *Daemon) setupResolvconfWatcher() error {
445 445
 						logrus.Debugf("Error retrieving updated host resolv.conf: %v", err)
446 446
 					} else if updatedResolvConf != nil {
447 447
 						// because the new host resolv.conf might have localhost nameservers..
448
-						updatedResolvConf, modified := resolvconf.FilterResolvDns(updatedResolvConf, daemon.config.EnableIPv6)
448
+						updatedResolvConf, modified := resolvconf.FilterResolvDns(updatedResolvConf, daemon.config.Bridge.EnableIPv6)
449 449
 						if modified {
450 450
 							// changes have occurred during localhost cleanup: generate an updated hash
451 451
 							newHash, err := utils.HashData(bytes.NewReader(updatedResolvConf))
... ...
@@ -653,7 +654,7 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID
653 653
 		Config:          config,
654 654
 		hostConfig:      &runconfig.HostConfig{},
655 655
 		ImageID:         imgID,
656
-		NetworkSettings: &NetworkSettings{},
656
+		NetworkSettings: &network.Settings{},
657 657
 		Name:            name,
658 658
 		Driver:          daemon.driver.String(),
659 659
 		ExecDriver:      daemon.execDriver.Name(),
... ...
@@ -807,16 +808,16 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService
807 807
 		config.Mtu = getDefaultNetworkMtu()
808 808
 	}
809 809
 	// Check for mutually incompatible config options
810
-	if config.BridgeIface != "" && config.BridgeIP != "" {
810
+	if config.Bridge.Iface != "" && config.Bridge.IP != "" {
811 811
 		return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")
812 812
 	}
813
-	if !config.EnableIptables && !config.InterContainerCommunication {
813
+	if !config.Bridge.EnableIptables && !config.Bridge.InterContainerCommunication {
814 814
 		return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
815 815
 	}
816
-	if !config.EnableIptables && config.EnableIpMasq {
817
-		config.EnableIpMasq = false
816
+	if !config.Bridge.EnableIptables && config.Bridge.EnableIpMasq {
817
+		config.Bridge.EnableIpMasq = false
818 818
 	}
819
-	config.DisableNetwork = config.BridgeIface == disableNetworkBridge
819
+	config.DisableNetwork = config.Bridge.Iface == disableNetworkBridge
820 820
 
821 821
 	// Claim the pidfile first, to avoid any and all unexpected race conditions.
822 822
 	// Some of the init doesn't need a pidfile lock - but let's not try to be smart.
... ...
@@ -948,20 +949,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService
948 948
 	}
949 949
 
950 950
 	if !config.DisableNetwork {
951
-		job := eng.Job("init_networkdriver")
952
-
953
-		job.SetenvBool("EnableIptables", config.EnableIptables)
954
-		job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)
955
-		job.SetenvBool("EnableIpForward", config.EnableIpForward)
956
-		job.SetenvBool("EnableIpMasq", config.EnableIpMasq)
957
-		job.SetenvBool("EnableIPv6", config.EnableIPv6)
958
-		job.Setenv("BridgeIface", config.BridgeIface)
959
-		job.Setenv("BridgeIP", config.BridgeIP)
960
-		job.Setenv("FixedCIDR", config.FixedCIDR)
961
-		job.Setenv("FixedCIDRv6", config.FixedCIDRv6)
962
-		job.Setenv("DefaultBindingIP", config.DefaultIp.String())
963
-
964
-		if err := job.Run(); err != nil {
951
+		if err := bridge.InitDriver(&config.Bridge); err != nil {
965 952
 			return nil, err
966 953
 		}
967 954
 	}
968 955
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+package network
1
+
2
+import "github.com/docker/docker/nat"
3
+
4
+type Settings struct {
5
+	IPAddress              string
6
+	IPPrefixLen            int
7
+	MacAddress             string
8
+	LinkLocalIPv6Address   string
9
+	LinkLocalIPv6PrefixLen int
10
+	GlobalIPv6Address      string
11
+	GlobalIPv6PrefixLen    int
12
+	Gateway                string
13
+	IPv6Gateway            string
14
+	Bridge                 string
15
+	PortMapping            map[string]map[string]string // Deprecated
16
+	Ports                  nat.PortMap
17
+}
0 18
deleted file mode 100644
... ...
@@ -1,23 +0,0 @@
1
-package daemon
2
-
3
-import (
4
-	"github.com/docker/docker/nat"
5
-)
6
-
7
-// FIXME: move deprecated port stuff to nat to clean up the core.
8
-type PortMapping map[string]string // Deprecated
9
-
10
-type NetworkSettings struct {
11
-	IPAddress              string
12
-	IPPrefixLen            int
13
-	MacAddress             string
14
-	LinkLocalIPv6Address   string
15
-	LinkLocalIPv6PrefixLen int
16
-	GlobalIPv6Address      string
17
-	GlobalIPv6PrefixLen    int
18
-	Gateway                string
19
-	IPv6Gateway            string
20
-	Bridge                 string
21
-	PortMapping            map[string]PortMapping // Deprecated
22
-	Ports                  nat.PortMap
23
-}
... ...
@@ -7,14 +7,15 @@ import (
7 7
 	"io/ioutil"
8 8
 	"net"
9 9
 	"os"
10
+	"strconv"
10 11
 	"strings"
11 12
 	"sync"
12 13
 
13 14
 	"github.com/Sirupsen/logrus"
15
+	"github.com/docker/docker/daemon/network"
14 16
 	"github.com/docker/docker/daemon/networkdriver"
15 17
 	"github.com/docker/docker/daemon/networkdriver/ipallocator"
16 18
 	"github.com/docker/docker/daemon/networkdriver/portmapper"
17
-	"github.com/docker/docker/engine"
18 19
 	"github.com/docker/docker/nat"
19 20
 	"github.com/docker/docker/pkg/iptables"
20 21
 	"github.com/docker/docker/pkg/parsers/kernel"
... ...
@@ -91,29 +92,34 @@ func initPortMapper() {
91 91
 	})
92 92
 }
93 93
 
94
-func InitDriver(job *engine.Job) error {
94
+type Config struct {
95
+	EnableIPv6                  bool
96
+	EnableIptables              bool
97
+	EnableIpForward             bool
98
+	EnableIpMasq                bool
99
+	DefaultIp                   net.IP
100
+	Iface                       string
101
+	IP                          string
102
+	FixedCIDR                   string
103
+	FixedCIDRv6                 string
104
+	InterContainerCommunication bool
105
+}
106
+
107
+func InitDriver(config *Config) error {
95 108
 	var (
96
-		networkv4      *net.IPNet
97
-		networkv6      *net.IPNet
98
-		addrv4         net.Addr
99
-		addrsv6        []net.Addr
100
-		enableIPTables = job.GetenvBool("EnableIptables")
101
-		enableIPv6     = job.GetenvBool("EnableIPv6")
102
-		icc            = job.GetenvBool("InterContainerCommunication")
103
-		ipMasq         = job.GetenvBool("EnableIpMasq")
104
-		ipForward      = job.GetenvBool("EnableIpForward")
105
-		bridgeIP       = job.Getenv("BridgeIP")
106
-		bridgeIPv6     = "fe80::1/64"
107
-		fixedCIDR      = job.Getenv("FixedCIDR")
108
-		fixedCIDRv6    = job.Getenv("FixedCIDRv6")
109
+		networkv4  *net.IPNet
110
+		networkv6  *net.IPNet
111
+		addrv4     net.Addr
112
+		addrsv6    []net.Addr
113
+		bridgeIPv6 = "fe80::1/64"
109 114
 	)
110 115
 	initPortMapper()
111 116
 
112
-	if defaultIP := job.Getenv("DefaultBindingIP"); defaultIP != "" {
113
-		defaultBindingIP = net.ParseIP(defaultIP)
117
+	if config.DefaultIp != nil {
118
+		defaultBindingIP = config.DefaultIp
114 119
 	}
115 120
 
116
-	bridgeIface = job.Getenv("BridgeIface")
121
+	bridgeIface = config.Iface
117 122
 	usingDefaultBridge := false
118 123
 	if bridgeIface == "" {
119 124
 		usingDefaultBridge = true
... ...
@@ -130,7 +136,7 @@ func InitDriver(job *engine.Job) error {
130 130
 		}
131 131
 
132 132
 		// If the iface is not found, try to create it
133
-		if err := configureBridge(bridgeIP, bridgeIPv6, enableIPv6); err != nil {
133
+		if err := configureBridge(config.IP, bridgeIPv6, config.EnableIPv6); err != nil {
134 134
 			return err
135 135
 		}
136 136
 
... ...
@@ -139,19 +145,19 @@ func InitDriver(job *engine.Job) error {
139 139
 			return err
140 140
 		}
141 141
 
142
-		if fixedCIDRv6 != "" {
142
+		if config.FixedCIDRv6 != "" {
143 143
 			// Setting route to global IPv6 subnet
144
-			logrus.Infof("Adding route to IPv6 network %q via device %q", fixedCIDRv6, bridgeIface)
145
-			if err := netlink.AddRoute(fixedCIDRv6, "", "", bridgeIface); err != nil {
146
-				logrus.Fatalf("Could not add route to IPv6 network %q via device %q", fixedCIDRv6, bridgeIface)
144
+			logrus.Infof("Adding route to IPv6 network %q via device %q", config.FixedCIDRv6, bridgeIface)
145
+			if err := netlink.AddRoute(config.FixedCIDRv6, "", "", bridgeIface); err != nil {
146
+				logrus.Fatalf("Could not add route to IPv6 network %q via device %q", config.FixedCIDRv6, bridgeIface)
147 147
 			}
148 148
 		}
149 149
 	} else {
150 150
 		// Bridge exists already, getting info...
151 151
 		// Validate that the bridge ip matches the ip specified by BridgeIP
152
-		if bridgeIP != "" {
152
+		if config.IP != "" {
153 153
 			networkv4 = addrv4.(*net.IPNet)
154
-			bip, _, err := net.ParseCIDR(bridgeIP)
154
+			bip, _, err := net.ParseCIDR(config.IP)
155 155
 			if err != nil {
156 156
 				return err
157 157
 			}
... ...
@@ -164,7 +170,7 @@ func InitDriver(job *engine.Job) error {
164 164
 		// (for example, an existing Docker installation that has only been used
165 165
 		// with IPv4 and docker0 already is set up) In that case, we can perform
166 166
 		// the bridge init for IPv6 here, else we will error out below if --ipv6=true
167
-		if len(addrsv6) == 0 && enableIPv6 {
167
+		if len(addrsv6) == 0 && config.EnableIPv6 {
168 168
 			if err := setupIPv6Bridge(bridgeIPv6); err != nil {
169 169
 				return err
170 170
 			}
... ...
@@ -175,10 +181,10 @@ func InitDriver(job *engine.Job) error {
175 175
 			}
176 176
 		}
177 177
 
178
-		// TODO: Check if route to fixedCIDRv6 is set
178
+		// TODO: Check if route to config.FixedCIDRv6 is set
179 179
 	}
180 180
 
181
-	if enableIPv6 {
181
+	if config.EnableIPv6 {
182 182
 		bip6, _, err := net.ParseCIDR(bridgeIPv6)
183 183
 		if err != nil {
184 184
 			return err
... ...
@@ -198,7 +204,7 @@ func InitDriver(job *engine.Job) error {
198 198
 
199 199
 	networkv4 = addrv4.(*net.IPNet)
200 200
 
201
-	if enableIPv6 {
201
+	if config.EnableIPv6 {
202 202
 		if len(addrsv6) == 0 {
203 203
 			return errors.New("IPv6 enabled but no IPv6 detected")
204 204
 		}
... ...
@@ -206,20 +212,20 @@ func InitDriver(job *engine.Job) error {
206 206
 	}
207 207
 
208 208
 	// Configure iptables for link support
209
-	if enableIPTables {
210
-		if err := setupIPTables(addrv4, icc, ipMasq); err != nil {
209
+	if config.EnableIptables {
210
+		if err := setupIPTables(addrv4, config.InterContainerCommunication, config.EnableIpMasq); err != nil {
211 211
 			return err
212 212
 		}
213 213
 
214 214
 	}
215 215
 
216
-	if ipForward {
216
+	if config.EnableIpForward {
217 217
 		// Enable IPv4 forwarding
218 218
 		if err := ioutil.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte{'1', '\n'}, 0644); err != nil {
219 219
 			logrus.Warnf("WARNING: unable to enable IPv4 forwarding: %s\n", err)
220 220
 		}
221 221
 
222
-		if fixedCIDRv6 != "" {
222
+		if config.FixedCIDRv6 != "" {
223 223
 			// Enable IPv6 forwarding
224 224
 			if err := ioutil.WriteFile("/proc/sys/net/ipv6/conf/default/forwarding", []byte{'1', '\n'}, 0644); err != nil {
225 225
 				logrus.Warnf("WARNING: unable to enable IPv6 default forwarding: %s\n", err)
... ...
@@ -235,7 +241,7 @@ func InitDriver(job *engine.Job) error {
235 235
 		return err
236 236
 	}
237 237
 
238
-	if enableIPTables {
238
+	if config.EnableIptables {
239 239
 		_, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Nat)
240 240
 		if err != nil {
241 241
 			return err
... ...
@@ -248,8 +254,8 @@ func InitDriver(job *engine.Job) error {
248 248
 	}
249 249
 
250 250
 	bridgeIPv4Network = networkv4
251
-	if fixedCIDR != "" {
252
-		_, subnet, err := net.ParseCIDR(fixedCIDR)
251
+	if config.FixedCIDR != "" {
252
+		_, subnet, err := net.ParseCIDR(config.FixedCIDR)
253 253
 		if err != nil {
254 254
 			return err
255 255
 		}
... ...
@@ -259,8 +265,8 @@ func InitDriver(job *engine.Job) error {
259 259
 		}
260 260
 	}
261 261
 
262
-	if fixedCIDRv6 != "" {
263
-		_, subnet, err := net.ParseCIDR(fixedCIDRv6)
262
+	if config.FixedCIDRv6 != "" {
263
+		_, subnet, err := net.ParseCIDR(config.FixedCIDRv6)
264 264
 		if err != nil {
265 265
 			return err
266 266
 		}
... ...
@@ -274,19 +280,6 @@ func InitDriver(job *engine.Job) error {
274 274
 	// Block BridgeIP in IP allocator
275 275
 	ipAllocator.RequestIP(bridgeIPv4Network, bridgeIPv4Network.IP)
276 276
 
277
-	// https://github.com/docker/docker/issues/2768
278
-	job.Eng.HackSetGlobalVar("httpapi.bridgeIP", bridgeIPv4Network.IP)
279
-
280
-	for name, f := range map[string]engine.Handler{
281
-		"allocate_interface": Allocate,
282
-		"release_interface":  Release,
283
-		"allocate_port":      AllocatePort,
284
-		"link":               LinkContainers,
285
-	} {
286
-		if err := job.Eng.Register(name, f); err != nil {
287
-			return err
288
-		}
289
-	}
290 277
 	return nil
291 278
 }
292 279
 
... ...
@@ -513,70 +506,67 @@ func linkLocalIPv6FromMac(mac string) (string, error) {
513 513
 }
514 514
 
515 515
 // Allocate a network interface
516
-func Allocate(job *engine.Job) error {
516
+func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Settings, error) {
517 517
 	var (
518
-		ip            net.IP
519
-		mac           net.HardwareAddr
520
-		err           error
521
-		id            = job.Args[0]
522
-		requestedIP   = net.ParseIP(job.Getenv("RequestedIP"))
523
-		requestedIPv6 = net.ParseIP(job.Getenv("RequestedIPv6"))
524
-		globalIPv6    net.IP
518
+		ip         net.IP
519
+		mac        net.HardwareAddr
520
+		err        error
521
+		globalIPv6 net.IP
525 522
 	)
526 523
 
527
-	ip, err = ipAllocator.RequestIP(bridgeIPv4Network, requestedIP)
524
+	ip, err = ipAllocator.RequestIP(bridgeIPv4Network, net.ParseIP(requestedIP))
528 525
 	if err != nil {
529
-		return err
526
+		return nil, err
530 527
 	}
531 528
 
532 529
 	// If no explicit mac address was given, generate a random one.
533
-	if mac, err = net.ParseMAC(job.Getenv("RequestedMac")); err != nil {
530
+	if mac, err = net.ParseMAC(requestedMac); err != nil {
534 531
 		mac = generateMacAddr(ip)
535 532
 	}
536 533
 
537 534
 	if globalIPv6Network != nil {
538 535
 		// If globalIPv6Network Size is at least a /80 subnet generate IPv6 address from MAC address
539 536
 		netmaskOnes, _ := globalIPv6Network.Mask.Size()
540
-		if requestedIPv6 == nil && netmaskOnes <= 80 {
541
-			requestedIPv6 = make(net.IP, len(globalIPv6Network.IP))
542
-			copy(requestedIPv6, globalIPv6Network.IP)
537
+		ipv6 := net.ParseIP(requestedIPv6)
538
+		if ipv6 == nil && netmaskOnes <= 80 {
539
+			ipv6 = make(net.IP, len(globalIPv6Network.IP))
540
+			copy(ipv6, globalIPv6Network.IP)
543 541
 			for i, h := range mac {
544
-				requestedIPv6[i+10] = h
542
+				ipv6[i+10] = h
545 543
 			}
546 544
 		}
547 545
 
548
-		globalIPv6, err = ipAllocator.RequestIP(globalIPv6Network, requestedIPv6)
546
+		globalIPv6, err = ipAllocator.RequestIP(globalIPv6Network, ipv6)
549 547
 		if err != nil {
550 548
 			logrus.Errorf("Allocator: RequestIP v6: %v", err)
551
-			return err
549
+			return nil, err
552 550
 		}
553 551
 		logrus.Infof("Allocated IPv6 %s", globalIPv6)
554 552
 	}
555 553
 
556
-	out := engine.Env{}
557
-	out.Set("IP", ip.String())
558
-	out.Set("Mask", bridgeIPv4Network.Mask.String())
559
-	out.Set("Gateway", bridgeIPv4Network.IP.String())
560
-	out.Set("MacAddress", mac.String())
561
-	out.Set("Bridge", bridgeIface)
562
-
563
-	size, _ := bridgeIPv4Network.Mask.Size()
564
-	out.SetInt("IPPrefixLen", size)
554
+	maskSize, _ := bridgeIPv4Network.Mask.Size()
565 555
 
566 556
 	// If linklocal IPv6
567 557
 	localIPv6Net, err := linkLocalIPv6FromMac(mac.String())
568 558
 	if err != nil {
569
-		return err
559
+		return nil, err
570 560
 	}
571 561
 	localIPv6, _, _ := net.ParseCIDR(localIPv6Net)
572
-	out.Set("LinkLocalIPv6", localIPv6.String())
573
-	out.Set("MacAddress", mac.String())
562
+
563
+	networkSettings := &network.Settings{
564
+		IPAddress:            ip.String(),
565
+		Gateway:              bridgeIPv4Network.IP.String(),
566
+		MacAddress:           mac.String(),
567
+		Bridge:               bridgeIface,
568
+		IPPrefixLen:          maskSize,
569
+		LinkLocalIPv6Address: localIPv6.String(),
570
+	}
574 571
 
575 572
 	if globalIPv6Network != nil {
576
-		out.Set("GlobalIPv6", globalIPv6.String())
577
-		sizev6, _ := globalIPv6Network.Mask.Size()
578
-		out.SetInt("GlobalIPv6PrefixLen", sizev6)
579
-		out.Set("IPv6Gateway", bridgeIPv6Addr.String())
573
+		networkSettings.GlobalIPv6Address = globalIPv6.String()
574
+		maskV6Size, _ := globalIPv6Network.Mask.Size()
575
+		networkSettings.GlobalIPv6PrefixLen = maskV6Size
576
+		networkSettings.IPv6Gateway = bridgeIPv6Addr.String()
580 577
 	}
581 578
 
582 579
 	currentInterfaces.Set(id, &networkInterface{
... ...
@@ -584,20 +574,15 @@ func Allocate(job *engine.Job) error {
584 584
 		IPv6: globalIPv6,
585 585
 	})
586 586
 
587
-	out.WriteTo(job.Stdout)
588
-
589
-	return nil
587
+	return networkSettings, nil
590 588
 }
591 589
 
592 590
 // Release an interface for a select ip
593
-func Release(job *engine.Job) error {
594
-	var (
595
-		id                 = job.Args[0]
596
-		containerInterface = currentInterfaces.Get(id)
597
-	)
591
+func Release(id string) {
592
+	var containerInterface = currentInterfaces.Get(id)
598 593
 
599 594
 	if containerInterface == nil {
600
-		return fmt.Errorf("No network information to release for %s", id)
595
+		logrus.Warnf("No network information to release for %s", id)
601 596
 	}
602 597
 
603 598
 	for _, nat := range containerInterface.PortMappings {
... ...
@@ -614,27 +599,21 @@ func Release(job *engine.Job) error {
614 614
 			logrus.Infof("Unable to release IPv6 %s", err)
615 615
 		}
616 616
 	}
617
-	return nil
618 617
 }
619 618
 
620 619
 // Allocate an external port and map it to the interface
621
-func AllocatePort(job *engine.Job) error {
620
+func AllocatePort(id string, port nat.Port, binding nat.PortBinding) (nat.PortBinding, error) {
622 621
 	var (
623
-		err error
624
-
625 622
 		ip            = defaultBindingIP
626
-		id            = job.Args[0]
627
-		hostIP        = job.Getenv("HostIP")
628
-		hostPort      = job.GetenvInt("HostPort")
629
-		containerPort = job.GetenvInt("ContainerPort")
630
-		proto         = job.Getenv("Proto")
623
+		proto         = port.Proto()
624
+		containerPort = port.Int()
631 625
 		network       = currentInterfaces.Get(id)
632 626
 	)
633 627
 
634
-	if hostIP != "" {
635
-		ip = net.ParseIP(hostIP)
628
+	if binding.HostIp != "" {
629
+		ip = net.ParseIP(binding.HostIp)
636 630
 		if ip == nil {
637
-			return fmt.Errorf("Bad parameter: invalid host ip %s", hostIP)
631
+			return nat.PortBinding{}, fmt.Errorf("Bad parameter: invalid host ip %s", binding.HostIp)
638 632
 		}
639 633
 	}
640 634
 
... ...
@@ -646,7 +625,7 @@ func AllocatePort(job *engine.Job) error {
646 646
 	case "udp":
647 647
 		container = &net.UDPAddr{IP: network.IP, Port: containerPort}
648 648
 	default:
649
-		return fmt.Errorf("unsupported address type %s", proto)
649
+		return nat.PortBinding{}, fmt.Errorf("unsupported address type %s", proto)
650 650
 	}
651 651
 
652 652
 	//
... ...
@@ -656,7 +635,14 @@ func AllocatePort(job *engine.Job) error {
656 656
 	// yields.
657 657
 	//
658 658
 
659
-	var host net.Addr
659
+	var (
660
+		host net.Addr
661
+		err  error
662
+	)
663
+	hostPort, err := nat.ParsePort(binding.HostPort)
664
+	if err != nil {
665
+		return nat.PortBinding{}, err
666
+	}
660 667
 	for i := 0; i < MaxAllocatedPortAttempts; i++ {
661 668
 		if host, err = portMapper.Map(container, ip, hostPort); err == nil {
662 669
 			break
... ...
@@ -671,36 +657,24 @@ func AllocatePort(job *engine.Job) error {
671 671
 	}
672 672
 
673 673
 	if err != nil {
674
-		return err
674
+		return nat.PortBinding{}, err
675 675
 	}
676 676
 
677 677
 	network.PortMappings = append(network.PortMappings, host)
678 678
 
679
-	out := engine.Env{}
680 679
 	switch netAddr := host.(type) {
681 680
 	case *net.TCPAddr:
682
-		out.Set("HostIP", netAddr.IP.String())
683
-		out.SetInt("HostPort", netAddr.Port)
681
+		return nat.PortBinding{HostIp: netAddr.IP.String(), HostPort: strconv.Itoa(netAddr.Port)}, nil
684 682
 	case *net.UDPAddr:
685
-		out.Set("HostIP", netAddr.IP.String())
686
-		out.SetInt("HostPort", netAddr.Port)
687
-	}
688
-	if _, err := out.WriteTo(job.Stdout); err != nil {
689
-		return err
683
+		return nat.PortBinding{HostIp: netAddr.IP.String(), HostPort: strconv.Itoa(netAddr.Port)}, nil
684
+	default:
685
+		return nat.PortBinding{}, fmt.Errorf("unsupported address type %T", netAddr)
690 686
 	}
691
-
692
-	return nil
693 687
 }
694 688
 
695
-func LinkContainers(job *engine.Job) error {
696
-	var (
697
-		action       = job.Args[0]
698
-		nfAction     iptables.Action
699
-		childIP      = job.Getenv("ChildIP")
700
-		parentIP     = job.Getenv("ParentIP")
701
-		ignoreErrors = job.GetenvBool("IgnoreErrors")
702
-		ports        = job.GetenvList("Ports")
703
-	)
689
+//TODO: should it return something more than just an error?
690
+func LinkContainers(action, parentIP, childIP string, ports []nat.Port, ignoreErrors bool) error {
691
+	var nfAction iptables.Action
704 692
 
705 693
 	switch action {
706 694
 	case "-A":
... ...
@@ -723,8 +697,7 @@ func LinkContainers(job *engine.Job) error {
723 723
 	}
724 724
 
725 725
 	chain := iptables.Chain{Name: "DOCKER", Bridge: bridgeIface}
726
-	for _, p := range ports {
727
-		port := nat.Port(p)
726
+	for _, port := range ports {
728 727
 		if err := chain.Link(nfAction, ip1, ip2, port.Int(), port.Proto()); !ignoreErrors && err != nil {
729 728
 			return err
730 729
 		}
... ...
@@ -6,8 +6,9 @@ import (
6 6
 	"strconv"
7 7
 	"testing"
8 8
 
9
+	"github.com/docker/docker/daemon/network"
9 10
 	"github.com/docker/docker/daemon/networkdriver/portmapper"
10
-	"github.com/docker/docker/engine"
11
+	"github.com/docker/docker/nat"
11 12
 	"github.com/docker/docker/pkg/iptables"
12 13
 )
13 14
 
... ...
@@ -16,7 +17,7 @@ func init() {
16 16
 	portmapper.NewProxy = portmapper.NewMockProxyCommand
17 17
 }
18 18
 
19
-func findFreePort(t *testing.T) int {
19
+func findFreePort(t *testing.T) string {
20 20
 	l, err := net.Listen("tcp", ":0")
21 21
 	if err != nil {
22 22
 		t.Fatal("Failed to find a free port")
... ...
@@ -27,143 +28,85 @@ func findFreePort(t *testing.T) int {
27 27
 	if err != nil {
28 28
 		t.Fatal("Failed to resolve address to identify free port")
29 29
 	}
30
-	return result.Port
31
-}
32
-
33
-func newPortAllocationJob(eng *engine.Engine, port int) (job *engine.Job) {
34
-	strPort := strconv.Itoa(port)
35
-
36
-	job = eng.Job("allocate_port", "container_id")
37
-	job.Setenv("HostIP", "127.0.0.1")
38
-	job.Setenv("HostPort", strPort)
39
-	job.Setenv("Proto", "tcp")
40
-	job.Setenv("ContainerPort", strPort)
41
-	return
42
-}
43
-
44
-func newPortAllocationJobWithInvalidHostIP(eng *engine.Engine, port int) (job *engine.Job) {
45
-	strPort := strconv.Itoa(port)
46
-
47
-	job = eng.Job("allocate_port", "container_id")
48
-	job.Setenv("HostIP", "localhost")
49
-	job.Setenv("HostPort", strPort)
50
-	job.Setenv("Proto", "tcp")
51
-	job.Setenv("ContainerPort", strPort)
52
-	return
30
+	return strconv.Itoa(result.Port)
53 31
 }
54 32
 
55 33
 func TestAllocatePortDetection(t *testing.T) {
56
-	eng := engine.New()
57
-	eng.Logging = false
58
-
59 34
 	freePort := findFreePort(t)
60 35
 
61
-	// Init driver
62
-	job := eng.Job("initdriver")
63
-	if res := InitDriver(job); res != nil {
36
+	if err := InitDriver(new(Config)); err != nil {
64 37
 		t.Fatal("Failed to initialize network driver")
65 38
 	}
66 39
 
67 40
 	// Allocate interface
68
-	job = eng.Job("allocate_interface", "container_id")
69
-	if res := Allocate(job); res != nil {
41
+	if _, err := Allocate("container_id", "", "", ""); err != nil {
70 42
 		t.Fatal("Failed to allocate network interface")
71 43
 	}
72 44
 
45
+	port := nat.Port(freePort + "/tcp")
46
+	binding := nat.PortBinding{HostIp: "127.0.0.1", HostPort: freePort}
47
+
73 48
 	// Allocate same port twice, expect failure on second call
74
-	job = newPortAllocationJob(eng, freePort)
75
-	if res := AllocatePort(job); res != nil {
49
+	if _, err := AllocatePort("container_id", port, binding); err != nil {
76 50
 		t.Fatal("Failed to find a free port to allocate")
77 51
 	}
78
-	if res := AllocatePort(job); res == nil {
52
+	if _, err := AllocatePort("container_id", port, binding); err == nil {
79 53
 		t.Fatal("Duplicate port allocation granted by AllocatePort")
80 54
 	}
81 55
 }
82 56
 
83 57
 func TestHostnameFormatChecking(t *testing.T) {
84
-	eng := engine.New()
85
-	eng.Logging = false
86
-
87 58
 	freePort := findFreePort(t)
88 59
 
89
-	// Init driver
90
-	job := eng.Job("initdriver")
91
-	if res := InitDriver(job); res != nil {
60
+	if err := InitDriver(new(Config)); err != nil {
92 61
 		t.Fatal("Failed to initialize network driver")
93 62
 	}
94 63
 
95 64
 	// Allocate interface
96
-	job = eng.Job("allocate_interface", "container_id")
97
-	if res := Allocate(job); res != nil {
65
+	if _, err := Allocate("container_id", "", "", ""); err != nil {
98 66
 		t.Fatal("Failed to allocate network interface")
99 67
 	}
100 68
 
101
-	// Allocate port with invalid HostIP, expect failure with Bad Request http status
102
-	job = newPortAllocationJobWithInvalidHostIP(eng, freePort)
103
-	if res := AllocatePort(job); res == nil {
69
+	port := nat.Port(freePort + "/tcp")
70
+	binding := nat.PortBinding{HostIp: "localhost", HostPort: freePort}
71
+
72
+	if _, err := AllocatePort("container_id", port, binding); err == nil {
104 73
 		t.Fatal("Failed to check invalid HostIP")
105 74
 	}
106 75
 }
107 76
 
108
-func newInterfaceAllocation(t *testing.T, input engine.Env) (output engine.Env) {
109
-	eng := engine.New()
110
-	eng.Logging = false
111
-
112
-	done := make(chan bool)
113
-
77
+func newInterfaceAllocation(t *testing.T, globalIPv6 *net.IPNet, requestedMac, requestedIP, requestedIPv6 string, expectFail bool) *network.Settings {
114 78
 	// set IPv6 global if given
115
-	if input.Exists("globalIPv6Network") {
116
-		_, globalIPv6Network, _ = net.ParseCIDR(input.Get("globalIPv6Network"))
79
+	if globalIPv6 != nil {
80
+		globalIPv6Network = globalIPv6
117 81
 	}
118 82
 
119
-	job := eng.Job("allocate_interface", "container_id")
120
-	job.Env().Init(&input)
121
-	reader, _ := job.Stdout.AddPipe()
122
-	go func() {
123
-		output.Decode(reader)
124
-		done <- true
125
-	}()
126
-
127
-	res := Allocate(job)
128
-	job.Stdout.Close()
129
-	<-done
130
-
131
-	if input.Exists("expectFail") && input.GetBool("expectFail") {
132
-		if res == nil {
133
-			t.Fatal("Doesn't fail to allocate network interface")
134
-		}
135
-	} else {
136
-		if res != nil {
137
-			t.Fatal("Failed to allocate network interface")
138
-		}
83
+	networkSettings, err := Allocate("container_id", requestedMac, requestedIP, requestedIPv6)
84
+	if err == nil && expectFail {
85
+		t.Fatal("Doesn't fail to allocate network interface")
86
+	} else if err != nil && !expectFail {
87
+		t.Fatal("Failed to allocate network interface")
88
+
139 89
 	}
140 90
 
141
-	if input.Exists("globalIPv6Network") {
91
+	if globalIPv6 != nil {
142 92
 		// check for bug #11427
143
-		_, subnet, _ := net.ParseCIDR(input.Get("globalIPv6Network"))
144
-		if globalIPv6Network.IP.String() != subnet.IP.String() {
93
+		if globalIPv6Network.IP.String() != globalIPv6.IP.String() {
145 94
 			t.Fatal("globalIPv6Network was modified during allocation")
146 95
 		}
147 96
 		// clean up IPv6 global
148 97
 		globalIPv6Network = nil
149 98
 	}
150 99
 
151
-	return
100
+	return networkSettings
152 101
 }
153 102
 
154 103
 func TestIPv6InterfaceAllocationAutoNetmaskGt80(t *testing.T) {
155
-
156
-	input := engine.Env{}
157
-
158 104
 	_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/81")
159
-
160
-	// set global ipv6
161
-	input.Set("globalIPv6Network", subnet.String())
162
-
163
-	output := newInterfaceAllocation(t, input)
105
+	networkSettings := newInterfaceAllocation(t, subnet, "", "", "", false)
164 106
 
165 107
 	// ensure low manually assigend global ip
166
-	ip := net.ParseIP(output.Get("GlobalIPv6"))
108
+	ip := net.ParseIP(networkSettings.GlobalIPv6Address)
167 109
 	_, subnet, _ = net.ParseCIDR(fmt.Sprintf("%s/%d", subnet.IP.String(), 120))
168 110
 	if !subnet.Contains(ip) {
169 111
 		t.Fatalf("Error ip %s not in subnet %s", ip.String(), subnet.String())
... ...
@@ -171,26 +114,18 @@ func TestIPv6InterfaceAllocationAutoNetmaskGt80(t *testing.T) {
171 171
 }
172 172
 
173 173
 func TestIPv6InterfaceAllocationAutoNetmaskLe80(t *testing.T) {
174
-
175
-	input := engine.Env{}
176
-
177 174
 	_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80")
178
-
179
-	// set global ipv6
180
-	input.Set("globalIPv6Network", subnet.String())
181
-	input.Set("RequestedMac", "ab:cd:ab:cd:ab:cd")
182
-
183
-	output := newInterfaceAllocation(t, input)
175
+	networkSettings := newInterfaceAllocation(t, subnet, "ab:cd:ab:cd:ab:cd", "", "", false)
184 176
 
185 177
 	// ensure global ip with mac
186
-	ip := net.ParseIP(output.Get("GlobalIPv6"))
178
+	ip := net.ParseIP(networkSettings.GlobalIPv6Address)
187 179
 	expectedIP := net.ParseIP("2001:db8:1234:1234:1234:abcd:abcd:abcd")
188 180
 	if ip.String() != expectedIP.String() {
189 181
 		t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
190 182
 	}
191 183
 
192 184
 	// ensure link local format
193
-	ip = net.ParseIP(output.Get("LinkLocalIPv6"))
185
+	ip = net.ParseIP(networkSettings.LinkLocalIPv6Address)
194 186
 	expectedIP = net.ParseIP("fe80::a9cd:abff:fecd:abcd")
195 187
 	if ip.String() != expectedIP.String() {
196 188
 		t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
... ...
@@ -199,27 +134,19 @@ func TestIPv6InterfaceAllocationAutoNetmaskLe80(t *testing.T) {
199 199
 }
200 200
 
201 201
 func TestIPv6InterfaceAllocationRequest(t *testing.T) {
202
-
203
-	input := engine.Env{}
204
-
205 202
 	_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80")
206
-	expectedIP := net.ParseIP("2001:db8:1234:1234:1234::1328")
207
-
208
-	// set global ipv6
209
-	input.Set("globalIPv6Network", subnet.String())
210
-	input.Set("RequestedIPv6", expectedIP.String())
203
+	expectedIP := "2001:db8:1234:1234:1234::1328"
211 204
 
212
-	output := newInterfaceAllocation(t, input)
205
+	networkSettings := newInterfaceAllocation(t, subnet, "", "", expectedIP, false)
213 206
 
214 207
 	// ensure global ip with mac
215
-	ip := net.ParseIP(output.Get("GlobalIPv6"))
216
-	if ip.String() != expectedIP.String() {
217
-		t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
208
+	ip := net.ParseIP(networkSettings.GlobalIPv6Address)
209
+	if ip.String() != expectedIP {
210
+		t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP)
218 211
 	}
219 212
 
220 213
 	// retry -> fails for duplicated address
221
-	input.SetBool("expectFail", true)
222
-	output = newInterfaceAllocation(t, input)
214
+	_ = newInterfaceAllocation(t, subnet, "", "", expectedIP, true)
223 215
 }
224 216
 
225 217
 func TestMacAddrGeneration(t *testing.T) {
... ...
@@ -239,40 +166,27 @@ func TestMacAddrGeneration(t *testing.T) {
239 239
 }
240 240
 
241 241
 func TestLinkContainers(t *testing.T) {
242
-	eng := engine.New()
243
-	eng.Logging = false
244
-
245 242
 	// Init driver
246
-	job := eng.Job("initdriver")
247
-	if res := InitDriver(job); res != nil {
243
+	if err := InitDriver(new(Config)); err != nil {
248 244
 		t.Fatal("Failed to initialize network driver")
249 245
 	}
250 246
 
251 247
 	// Allocate interface
252
-	job = eng.Job("allocate_interface", "container_id")
253
-	if res := Allocate(job); res != nil {
248
+	if _, err := Allocate("container_id", "", "", ""); err != nil {
254 249
 		t.Fatal("Failed to allocate network interface")
255 250
 	}
256 251
 
257
-	job.Args[0] = "-I"
258
-
259
-	job.Setenv("ChildIP", "172.17.0.2")
260
-	job.Setenv("ParentIP", "172.17.0.1")
261
-	job.SetenvBool("IgnoreErrors", false)
262
-	job.SetenvList("Ports", []string{"1234"})
263
-
264 252
 	bridgeIface = "lo"
265
-	_, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Filter)
266
-	if err != nil {
253
+	if _, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Filter); err != nil {
267 254
 		t.Fatal(err)
268 255
 	}
269 256
 
270
-	if res := LinkContainers(job); res != nil {
271
-		t.Fatalf("LinkContainers failed")
257
+	if err := LinkContainers("-I", "172.17.0.1", "172.17.0.2", []nat.Port{nat.Port("1234")}, false); err != nil {
258
+		t.Fatal("LinkContainers failed")
272 259
 	}
273 260
 
274 261
 	// flush rules
275
-	if _, err = iptables.Raw([]string{"-F", "DOCKER"}...); err != nil {
262
+	if _, err := iptables.Raw([]string{"-F", "DOCKER"}...); err != nil {
276 263
 		t.Fatal(err)
277 264
 	}
278 265
 
... ...
@@ -18,6 +18,7 @@ import (
18 18
 
19 19
 	"github.com/docker/docker/builtins"
20 20
 	"github.com/docker/docker/daemon"
21
+	"github.com/docker/docker/daemon/networkdriver/bridge"
21 22
 	"github.com/docker/docker/engine"
22 23
 	flag "github.com/docker/docker/pkg/mflag"
23 24
 	"github.com/docker/docker/registry"
... ...
@@ -185,9 +186,11 @@ func newTestEngine(t Fataler, autorestart bool, root string) *engine.Engine {
185 185
 		ExecDriver:  "native",
186 186
 		// Either InterContainerCommunication or EnableIptables must be set,
187 187
 		// otherwise NewDaemon will fail because of conflicting settings.
188
-		InterContainerCommunication: true,
189
-		TrustKeyPath:                filepath.Join(root, "key.json"),
190
-		LogConfig:                   runconfig.LogConfig{Type: "json-file"},
188
+		Bridge: bridge.Config{
189
+			InterContainerCommunication: true,
190
+		},
191
+		TrustKeyPath: filepath.Join(root, "key.json"),
192
+		LogConfig:    runconfig.LogConfig{Type: "json-file"},
191 193
 	}
192 194
 	d, err := daemon.NewDaemon(cfg, eng, registry.NewService(nil))
193 195
 	if err != nil {
... ...
@@ -2,10 +2,12 @@ package links
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"github.com/docker/docker/engine"
6
-	"github.com/docker/docker/nat"
7 5
 	"path"
8 6
 	"strings"
7
+
8
+	"github.com/docker/docker/daemon/networkdriver/bridge"
9
+	"github.com/docker/docker/engine"
10
+	"github.com/docker/docker/nat"
9 11
 )
10 12
 
11 13
 type Link struct {
... ...
@@ -158,21 +160,5 @@ func (l *Link) Disable() {
158 158
 }
159 159
 
160 160
 func (l *Link) toggle(action string, ignoreErrors bool) error {
161
-	job := l.eng.Job("link", action)
162
-
163
-	job.Setenv("ParentIP", l.ParentIP)
164
-	job.Setenv("ChildIP", l.ChildIP)
165
-	job.SetenvBool("IgnoreErrors", ignoreErrors)
166
-
167
-	out := make([]string, len(l.Ports))
168
-	for i, p := range l.Ports {
169
-		out[i] = string(p)
170
-	}
171
-	job.SetenvList("Ports", out)
172
-
173
-	if err := job.Run(); err != nil {
174
-		// TODO: get ouput from job
175
-		return err
176
-	}
177
-	return nil
161
+	return bridge.LinkContainers(action, l.ParentIP, l.ChildIP, l.Ports, ignoreErrors)
178 162
 }
... ...
@@ -34,6 +34,9 @@ func NewPort(proto, port string) Port {
34 34
 }
35 35
 
36 36
 func ParsePort(rawPort string) (int, error) {
37
+	if len(rawPort) == 0 {
38
+		return 0, nil
39
+	}
37 40
 	port, err := strconv.ParseUint(rawPort, 10, 16)
38 41
 	if err != nil {
39 42
 		return 0, err