Browse code

Validate `--ip` and `--ip6` for `docker create`

This fix tries to fix the issue raised in 25863 where `--ip` value
is not validated for `docker create`. As a result, the IP address
passed by `--ip` is not used for `docker create` (ignored silently).

This fix adds validation in the daemon so that `--ip` and `--ip6`
are properly validated for `docker create`.

An integration test has been added to cover the changes.

This fix fixes 25863.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/08/23 13:52:56
Showing 2 changed files
... ...
@@ -2,6 +2,7 @@ package daemon
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"net"
5 6
 	"strings"
6 7
 
7 8
 	"github.com/Sirupsen/logrus"
... ...
@@ -244,8 +245,22 @@ func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *i
244 244
 }
245 245
 
246 246
 // Checks if the client set configurations for more than one network while creating a container
247
+// Also checks if the IPAMConfig is valid
247 248
 func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
248
-	if nwConfig == nil || len(nwConfig.EndpointsConfig) <= 1 {
249
+	if nwConfig == nil || len(nwConfig.EndpointsConfig) == 0 {
250
+		return nil
251
+	}
252
+	if len(nwConfig.EndpointsConfig) == 1 {
253
+		for _, v := range nwConfig.EndpointsConfig {
254
+			if v.IPAMConfig != nil {
255
+				if v.IPAMConfig.IPv4Address != "" && net.ParseIP(v.IPAMConfig.IPv4Address).To4() == nil {
256
+					return errors.NewBadRequestError(fmt.Errorf("invalid IPv4 address: %s", v.IPAMConfig.IPv4Address))
257
+				}
258
+				if v.IPAMConfig.IPv6Address != "" && net.ParseIP(v.IPAMConfig.IPv6Address).To16() == nil {
259
+					return errors.NewBadRequestError(fmt.Errorf("invalid IPv6 address: %s", v.IPAMConfig.IPv6Address))
260
+				}
261
+			}
262
+		}
249 263
 		return nil
250 264
 	}
251 265
 	l := make([]string, 0, len(nwConfig.EndpointsConfig))
... ...
@@ -1717,3 +1717,20 @@ func (s *DockerNetworkSuite) TestDockerNetworkFlagAlias(c *check.C) {
1717 1717
 	output, status, _ = dockerCmdWithError("run", "--rm", "--network=user", "--net-alias=foo", "--network-alias=bar", "busybox", "true")
1718 1718
 	c.Assert(status, checker.Equals, 0, check.Commentf("unexpected status code %d (%s)", status, output))
1719 1719
 }
1720
+
1721
+func (s *DockerNetworkSuite) TestDockerNetworkValidateIP(c *check.C) {
1722
+	_, _, err := dockerCmdWithError("network", "create", "--ipv6", "--subnet=172.28.0.0/16", "--subnet=2001:db8:1234::/64", "mynet")
1723
+	c.Assert(err, check.IsNil)
1724
+	assertNwIsAvailable(c, "mynet")
1725
+
1726
+	_, _, err = dockerCmdWithError("run", "-d", "--name", "mynet0", "--net=mynet", "--ip", "172.28.99.88", "--ip6", "2001:db8:1234::9988", "busybox", "top")
1727
+	c.Assert(err, check.IsNil)
1728
+	c.Assert(waitRun("mynet0"), check.IsNil)
1729
+	verifyIPAddressConfig(c, "mynet0", "mynet", "172.28.99.88", "2001:db8:1234::9988")
1730
+	verifyIPAddresses(c, "mynet0", "mynet", "172.28.99.88", "2001:db8:1234::9988")
1731
+
1732
+	_, _, err = dockerCmdWithError("run", "--net=mynet", "--ip", "mynet_ip", "--ip6", "2001:db8:1234::9999", "busybox", "top")
1733
+	c.Assert(err.Error(), checker.Contains, "invalid IPv4 address")
1734
+	_, _, err = dockerCmdWithError("run", "--net=mynet", "--ip", "172.28.99.99", "--ip6", "mynet_ip6", "busybox", "top")
1735
+	c.Assert(err.Error(), checker.Contains, "invalid IPv6 address")
1736
+}