diff --git a/libnetwork/network.go b/libnetwork/network.go index 6ea3e6acb0..466eccb21c 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -1577,16 +1577,18 @@ func (n *Network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error { } }() - if gws, ok := d.Meta[netlabel.Gateway]; ok { - if d.Gateway, err = types.ParseCIDR(gws); err != nil { - return types.InvalidParameterErrorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err) + // If there's no user-configured gateway address but the IPAM driver returned a gw when it + // set up the pool, use it. (It doesn't need to be requested/reserved in IPAM.) + if cfg.Gateway == "" { + if gws, ok := d.Meta[netlabel.Gateway]; ok { + if d.Gateway, err = types.ParseCIDR(gws); err != nil { + return types.InvalidParameterErrorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err) + } } } - // If user requested a specific gateway, libnetwork will allocate it - // irrespective of whether ipam driver returned a gateway already. - // If none of the above is true, libnetwork will allocate one. - if cfg.Gateway != "" || d.Gateway == nil { + // If there's still no gateway, reserve cfg.Gateway or let the IPAM driver select an address. + if d.Gateway == nil { gatewayOpts := map[string]string{ ipamapi.RequestAddressType: netlabel.Gateway, }