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>
... | ... |
@@ -41,6 +41,7 @@ import ( |
41 | 41 |
rsystem "github.com/opencontainers/runc/libcontainer/system" |
42 | 42 |
"github.com/opencontainers/runc/libcontainer/user" |
43 | 43 |
specs "github.com/opencontainers/runtime-spec/specs-go" |
44 |
+ "github.com/pkg/errors" |
|
44 | 45 |
"github.com/vishvananda/netlink" |
45 | 46 |
) |
46 | 47 |
|
... | ... |
@@ -710,13 +711,30 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e |
710 | 710 |
|
711 | 711 |
ipamV4Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)} |
712 | 712 |
|
713 |
- nw, nw6List, err := netutils.ElectInterfaceAddresses(bridgeName) |
|
714 |
- if err == nil { |
|
715 |
- ipamV4Conf.PreferredPool = lntypes.GetIPNetCanonical(nw).String() |
|
716 |
- hip, _ := lntypes.GetHostPartIP(nw.IP, nw.Mask) |
|
717 |
- if hip.IsGlobalUnicast() { |
|
718 |
- ipamV4Conf.Gateway = nw.IP.String() |
|
713 |
+ nwList, nw6List, err := netutils.ElectInterfaceAddresses(bridgeName) |
|
714 |
+ if err != nil { |
|
715 |
+ return errors.Wrap(err, "list bridge addresses failed") |
|
716 |
+ } |
|
717 |
+ |
|
718 |
+ nw := nwList[0] |
|
719 |
+ if len(nwList) > 1 && config.bridgeConfig.FixedCIDR != "" { |
|
720 |
+ _, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR) |
|
721 |
+ if err != nil { |
|
722 |
+ return errors.Wrap(err, "parse CIDR failed") |
|
719 | 723 |
} |
724 |
+ // Iterate through in case there are multiple addresses for the bridge |
|
725 |
+ for _, entry := range nwList { |
|
726 |
+ if fCIDR.Contains(entry.IP) { |
|
727 |
+ nw = entry |
|
728 |
+ break |
|
729 |
+ } |
|
730 |
+ } |
|
731 |
+ } |
|
732 |
+ |
|
733 |
+ ipamV4Conf.PreferredPool = lntypes.GetIPNetCanonical(nw).String() |
|
734 |
+ hip, _ := lntypes.GetHostPartIP(nw.IP, nw.Mask) |
|
735 |
+ if hip.IsGlobalUnicast() { |
|
736 |
+ ipamV4Conf.Gateway = nw.IP.String() |
|
720 | 737 |
} |
721 | 738 |
|
722 | 739 |
if config.bridgeConfig.IP != "" { |