1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Fix issue for --fixed-cidr when bridge has multiple addresses

This fix tries to address the issue raised in 26341
where multiple addresses in a bridge may cause `--fixed-cidr`
to not have the correct addresses.

The issue is that `netutils.ElectInterfaceAddresses(bridgeName)`
only returns the first IPv4 address.

This fix (together with the PR created in libnetwork )
changes `ElectInterfaceAddresses()` and `addresses()`
so that all IPv4 addresses are returned. This will allow the
possibility of selectively choose the address needed.

In `daemon_unix.go`, bridge address is chosen by comparing with
the `--fixed-cidr` first, thus resolve the issue in 26341.

This fix is tested manually, as is described in 26341:
```
brctl addbr cbr0
ip addr add 10.111.111.111/20 dev cbr0 label cbr0:main
ip addr add 10.222.222.222/12 dev cbr0 label cbr0:docker
ip link set cbr0 up
docker daemon --bridge=cbr0 --iptables=false --ip-masq=false --fixed-cidr=10.222.222.222/24
docker run --rm busybox ip route get 8.8.8.8 | grep -Po 'src.*'
src 10.222.222.0
```

This fix fixes 26341.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2016-09-16 22:46:20 -07:00
parent 2428534998
commit e9c4c513d1

View file

@ -41,6 +41,7 @@ import (
rsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/user"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/vishvananda/netlink"
)
@ -710,13 +711,30 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
ipamV4Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)}
nw, nw6List, err := netutils.ElectInterfaceAddresses(bridgeName)
if err == nil {
ipamV4Conf.PreferredPool = lntypes.GetIPNetCanonical(nw).String()
hip, _ := lntypes.GetHostPartIP(nw.IP, nw.Mask)
if hip.IsGlobalUnicast() {
ipamV4Conf.Gateway = nw.IP.String()
nwList, nw6List, err := netutils.ElectInterfaceAddresses(bridgeName)
if err != nil {
return errors.Wrap(err, "list bridge addresses failed")
}
nw := nwList[0]
if len(nwList) > 1 && config.bridgeConfig.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR)
if err != nil {
return errors.Wrap(err, "parse CIDR failed")
}
// Iterate through in case there are multiple addresses for the bridge
for _, entry := range nwList {
if fCIDR.Contains(entry.IP) {
nw = entry
break
}
}
}
ipamV4Conf.PreferredPool = lntypes.GetIPNetCanonical(nw).String()
hip, _ := lntypes.GetHostPartIP(nw.IP, nw.Mask)
if hip.IsGlobalUnicast() {
ipamV4Conf.Gateway = nw.IP.String()
}
if config.bridgeConfig.IP != "" {