Skip to content

Commit 2f1c05d

Browse files
committed
Merge pull request moby#1374 from dotcloud/steeve-patch-1
- Runtime: Handle ip route showing mask-less IP addresses
2 parents baa4618 + f5a8e90 commit 2f1c05d

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

network.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,29 @@ func iptables(args ...string) error {
9393
return nil
9494
}
9595

96-
func checkRouteOverlaps(dockerNetwork *net.IPNet) error {
97-
output, err := ip("route")
98-
if err != nil {
99-
return err
100-
}
101-
utils.Debugf("Routes:\n\n%s", output)
102-
for _, line := range strings.Split(output, "\n") {
96+
func checkRouteOverlaps(routes string, dockerNetwork *net.IPNet) error {
97+
utils.Debugf("Routes:\n\n%s", routes)
98+
for _, line := range strings.Split(routes, "\n") {
10399
if strings.Trim(line, "\r\n\t ") == "" || strings.Contains(line, "default") {
104100
continue
105101
}
106-
if _, network, err := net.ParseCIDR(strings.Split(line, " ")[0]); err != nil {
107-
return fmt.Errorf("Unexpected ip route output: %s (%s)", err, line)
108-
} else if networkOverlaps(dockerNetwork, network) {
109-
return fmt.Errorf("Network %s is already routed: '%s'", dockerNetwork.String(), line)
102+
_, network, err := net.ParseCIDR(strings.Split(line, " ")[0])
103+
if err != nil {
104+
// is this a mask-less IP address?
105+
if ip := net.ParseIP(strings.Split(line, " ")[0]); ip == nil {
106+
// fail only if it's neither a network nor a mask-less IP address
107+
return fmt.Errorf("Unexpected ip route output: %s (%s)", err, line)
108+
} else {
109+
_, network, err = net.ParseCIDR(ip.String() + "/32")
110+
if err != nil {
111+
return err
112+
}
113+
}
114+
}
115+
if err == nil && network != nil {
116+
if networkOverlaps(dockerNetwork, network) {
117+
return fmt.Errorf("Network %s is already routed: '%s'", dockerNetwork, line)
118+
}
110119
}
111120
}
112121
return nil
@@ -142,7 +151,11 @@ func CreateBridgeIface(ifaceName string) error {
142151
if err != nil {
143152
return err
144153
}
145-
if err := checkRouteOverlaps(dockerNetwork); err == nil {
154+
routes, err := ip("route")
155+
if err != nil {
156+
return err
157+
}
158+
if err := checkRouteOverlaps(routes, dockerNetwork); err == nil {
146159
ifaceAddr = addr
147160
break
148161
} else {

network_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,22 @@ func TestNetworkOverlaps(t *testing.T) {
383383
//netX starts and ends before netY
384384
AssertNoOverlap("172.16.1.1/25", "172.16.2.1/24", t)
385385
}
386+
387+
func TestCheckRouteOverlaps(t *testing.T) {
388+
routes := `default via 10.0.2.2 dev eth0
389+
10.0.2.0 dev eth0 proto kernel scope link src 10.0.2.15
390+
10.0.3.0/24 dev lxcbr0 proto kernel scope link src 10.0.3.1
391+
10.0.42.0/24 dev testdockbr0 proto kernel scope link src 10.0.42.1
392+
172.16.42.0/24 dev docker0 proto kernel scope link src 172.16.42.1
393+
192.168.142.0/24 dev eth1 proto kernel scope link src 192.168.142.142`
394+
395+
_, netX, _ := net.ParseCIDR("172.16.0.1/24")
396+
if err := checkRouteOverlaps(routes, netX); err != nil {
397+
t.Fatal(err)
398+
}
399+
400+
_, netX, _ = net.ParseCIDR("10.0.2.0/24")
401+
if err := checkRouteOverlaps(routes, netX); err == nil {
402+
t.Fatalf("10.0.2.0/24 and 10.0.2.0 should overlap but it doesn't")
403+
}
404+
}

0 commit comments

Comments
 (0)