From 9816bfcaf58a609d64d648043c10817c27dcfa36 Mon Sep 17 00:00:00 2001 From: selansen Date: Wed, 29 Aug 2018 23:28:22 -0400 Subject: [PATCH 1/2] Global Default AddressPool - Update Addressing few review comments as part of code refactoring. Also moved validation logic from CLI to Moby. Signed-off-by: selansen (cherry picked from commit 148ff00a0a800fad99de11ee3021d4c5d4869157) Signed-off-by: Sebastiaan van Stijn --- daemon/cluster/listen_addr.go | 31 +++++++++++++++++++++++++++++ daemon/cluster/swarm.go | 4 ++++ integration/network/service_test.go | 2 +- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/daemon/cluster/listen_addr.go b/daemon/cluster/listen_addr.go index e1ebfec8df580..4ca2d5104de8a 100644 --- a/daemon/cluster/listen_addr.go +++ b/daemon/cluster/listen_addr.go @@ -3,6 +3,7 @@ package cluster // import "github.com/docker/docker/daemon/cluster" import ( "fmt" "net" + "strings" ) const ( @@ -87,6 +88,36 @@ func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (st return systemAddr.String(), listenAddrPort, nil } +// validateDefaultAddrPool validates default address pool +// it also strips white space from the string before validation +func validateDefaultAddrPool(defaultAddrPool []string, size uint32) error { + if defaultAddrPool == nil { + // defaultAddrPool is not defined + return nil + } + //if size is not set, then we use default value 24 + if size == 0 { + size = 24 + } + if size > 32 { + return fmt.Errorf("subnet size is out of range: %d", size) + } + for i := range defaultAddrPool { + // trim leading and trailing white spaces + defaultAddrPool[i] = strings.TrimSpace(defaultAddrPool[i]) + _, b, err := net.ParseCIDR(defaultAddrPool[i]) + if err != nil { + return fmt.Errorf("invalid base pool %s: %v", defaultAddrPool[i], err) + } + ones, _ := b.Mask.Size() + if size < uint32(ones) { + return fmt.Errorf("invalid CIDR: %q. Subnet size is too small for pool: %d", defaultAddrPool[i], size) + } + } + + return nil +} + func resolveDataPathAddr(dataPathAddr string) (string, error) { if dataPathAddr == "" { // dataPathAddr is not defined diff --git a/daemon/cluster/swarm.go b/daemon/cluster/swarm.go index d61e22f4fc156..65dfe9eb45a05 100644 --- a/daemon/cluster/swarm.go +++ b/daemon/cluster/swarm.go @@ -92,6 +92,10 @@ func (c *Cluster) Init(req types.InitRequest) (string, error) { } } + //Validate Default Address Pool input + if err := validateDefaultAddrPool(req.DefaultAddrPool, req.SubnetSize); err != nil { + return "", err + } nr, err := c.newNodeRunner(nodeStartConfig{ forceNewCluster: req.ForceNewCluster, autolock: req.AutoLockManagers, diff --git a/integration/network/service_test.go b/integration/network/service_test.go index 739a8ecb7d950..40823da452111 100644 --- a/integration/network/service_test.go +++ b/integration/network/service_test.go @@ -355,7 +355,7 @@ func TestServiceWithDefaultAddressPoolInit(t *testing.T) { d.Stop(t) // Clean up , set it back to original one to make sure other tests don't fail - ipAddr = []string{"10.10.0.0/8"} + ipAddr = []string{"10.0.0.0/8"} ops = append(ops, daemon.WithSwarmDefaultAddrPool(ipAddr)) ops = append(ops, daemon.WithSwarmDefaultAddrPoolSubnetSize(24)) d = swarm.NewSwarm(t, testEnv, ops...) From 9406f3622d18a0d9b6c438190e8fdd8be53d3b22 Mon Sep 17 00:00:00 2001 From: selansen Date: Tue, 2 Oct 2018 15:52:11 -0400 Subject: [PATCH 2/2] Fix for default-addr-pool-mask-length param max value check We check for max value for -default-addr-pool-mask-length param as 32. But There won't be enough addresses on the overlay network. Hence we are keeping it 29 so that we would be having atleast 8 addresses in /29 network. Signed-off-by: selansen (cherry picked from commit d25c5df80e60cdbdc23fe3d0e2a6808123643dc7) Signed-off-by: Sebastiaan van Stijn --- daemon/cluster/listen_addr.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/daemon/cluster/listen_addr.go b/daemon/cluster/listen_addr.go index 4ca2d5104de8a..44ea5fce42f31 100644 --- a/daemon/cluster/listen_addr.go +++ b/daemon/cluster/listen_addr.go @@ -99,7 +99,12 @@ func validateDefaultAddrPool(defaultAddrPool []string, size uint32) error { if size == 0 { size = 24 } - if size > 32 { + // We allow max value as 29. We can have 8 IP addresses for max value 29 + // If we allow 30, then we will get only 4 IP addresses. But with latest + // libnetwork LB scale implementation, we use total of 4 IP addresses for internal use. + // Hence keeping 29 as max value, we will have 8 IP addresses. This will be + // smallest subnet that can be used in overlay network. + if size > 29 { return fmt.Errorf("subnet size is out of range: %d", size) } for i := range defaultAddrPool {