Adds workaround for routing 169.254.x.x addresses

See: https://bugs.launchpad.net/quantum/+bug/1174657
This commit is contained in:
Alessandro Pilotti 2013-05-01 15:25:44 +03:00
parent dcafa75141
commit 4b08f9ef93
3 changed files with 90 additions and 0 deletions

View File

@ -16,10 +16,12 @@
import posixpath
import urllib2
import urlparse
from cloudbaseinit.metadata.services import base
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.openstack.common import log as logging
from cloudbaseinit.osutils import factory as osutils_factory
opts = [
cfg.StrOpt('metadata_base_url', default='http://169.254.169.254/',
@ -37,8 +39,38 @@ class HttpService(base.BaseMetadataService):
super(HttpService, self).__init__()
self._enable_retry = True
def _check_metadata_ip_route(self):
'''
Workaround for: https://bugs.launchpad.net/quantum/+bug/1174657
'''
osutils = osutils_factory.OSUtilsFactory().get_os_utils()
os_major_version = int(osutils.get_os_version().split('.')[0])
if os_major_version >= 6:
# 169.254.x.x addresses are not getting routed starting from
# Windows Vista / 2008
metadata_netloc = urlparse.urlparse(CONF.metadata_base_url).netloc
metadata_host = metadata_netloc.split(':')[0]
if metadata_host.startswith("169.254."):
if not osutils.check_static_route_exists(metadata_host):
(interface_index, gateway) = osutils.get_default_gateway()
if gateway:
try:
osutils.add_static_route(metadata_host,
"255.255.255.255",
gateway,
interface_index,
10)
except Exception, ex:
# Ignore it
LOG.exception(ex)
def load(self):
super(HttpService, self).load()
self._check_metadata_ip_route()
try:
self.get_meta_data('openstack')
return True

View File

@ -69,3 +69,16 @@ class BaseOSUtils(object):
def terminate(self):
pass
def get_default_gateway(self):
pass
def check_static_route_exists(self, destination):
pass
def add_static_route(self, destination, mask, next_hop, interface_index,
metric):
pass
def get_os_version(self):
pass

View File

@ -327,3 +327,48 @@ class WindowsUtils(base.BaseOSUtils):
# is not enough
time.sleep(3)
self._stop_service(self._service_name)
def get_default_gateway(self):
conn = wmi.WMI(moniker='//./root/cimv2')
for net_adapter_config in conn.Win32_NetworkAdapterConfiguration():
if net_adapter_config.DefaultIPGateway:
return (net_adapter_config.InterfaceIndex,
net_adapter_config.DefaultIPGateway[0])
return (None, None)
def check_static_route_exists(self, destination):
conn = wmi.WMI(moniker='//./root/cimv2')
return len(conn.Win32_IP4RouteTable(Destination=destination)) > 0
def add_static_route(self, destination, mask, next_hop, interface_index,
metric):
args = ['ROUTE', 'ADD', destination, 'MASK', mask, next_hop]
(out, err, ret_val) = self.execute_process(args)
# Cannot use the return value to determine the outcome
if err:
raise Exception('Unable to add route: %(err)s' % locals())
# TODO(alexpilotti): The following code creates the route properly and
# "route print" shows the added route, but routing to the destination
# fails. This option would be preferable compared to spawning a
# "ROUTE ADD" process.
'''
ROUTE_PROTOCOL_NETMGMT = 3
ROUTE_TYPE_INDIRECT = 4
conn = wmi.WMI(moniker='//./root/cimv2')
route = conn.Win32_IP4RouteTable.SpawnInstance_()
route.Destination = destination
route.Mask = mask
route.NextHop = next_hop
route.InterfaceIndex = interface_index
route.Metric1 = metric
route.Protocol = self.ROUTE_PROTOCOL_NETMGMT
route.Type = self.ROUTE_TYPE_INDIRECT
route.Put_()
'''
def get_os_version(self):
conn = wmi.WMI(moniker='//./root/cimv2')
return conn.Win32_OperatingSystem()[0].Version