summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorDan Smith <danms@us.ibm.com>2012-06-22 10:15:42 -0700
committerDan Smith <danms@us.ibm.com>2012-06-25 13:17:23 -0700
commit76a7a3540b3e2f111c267df83fb0b528dd8c6fa5 (patch)
treeacdded8bc48abc09edaf119338b89d49485db7e3 /nova
parentad6b11c17c8afd6522d9e9dce269e3f51b5b0851 (diff)
downloadnova-76a7a3540b3e2f111c267df83fb0b528dd8c6fa5.tar.gz
nova-76a7a3540b3e2f111c267df83fb0b528dd8c6fa5.tar.xz
nova-76a7a3540b3e2f111c267df83fb0b528dd8c6fa5.zip
Migrate existing routes from flat_interface
Right now, any routes that exist on flat_interface (other than the default route) get lost when we set up the bridge. This patch migrates them over to avoid losing that connectivity. It does so by using 'ip route' instead of 'route', which is much easier to script and is consistent with other use of iproute2 tools in linux_net.py. Bug 962822 Change-Id: I7d9e8e05169f2f87e8481595397c02fd3a3612f4
Diffstat (limited to 'nova')
-rw-r--r--nova/network/linux_net.py49
-rw-r--r--nova/tests/network/test_linux_net.py20
2 files changed, 38 insertions, 31 deletions
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index 42fb9cc10..828174b3a 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -548,24 +548,27 @@ def initialize_gateway_device(dev, network_ref):
if ip_params[0] != full_ip:
new_ip_params.append(ip_params)
if not old_ip_params or old_ip_params[0][0] != full_ip:
- gateway = None
- out, err = _execute('route', '-n', run_as_root=True)
- for line in out.split('\n'):
- fields = line.split()
- if fields and fields[0] == '0.0.0.0' and fields[-1] == dev:
- gateway = fields[1]
- _execute('route', 'del', 'default', 'gw', gateway,
- 'dev', dev, run_as_root=True,
- check_exit_code=[0, 7])
+ old_routes = []
+ result = _execute('ip', 'route', 'show', 'dev', dev,
+ run_as_root=True)
+ if result:
+ out, err = result
+ for line in out.split('\n'):
+ fields = line.split()
+ if fields and 'via' in fields:
+ old_routes.append(fields)
+ _execute('ip', 'route', 'del', fields[0],
+ 'dev', dev, run_as_root=True)
for ip_params in old_ip_params:
_execute(*_ip_bridge_cmd('del', ip_params, dev),
run_as_root=True, check_exit_code=[0, 2, 254])
for ip_params in new_ip_params:
_execute(*_ip_bridge_cmd('add', ip_params, dev),
run_as_root=True, check_exit_code=[0, 2, 254])
- if gateway:
- _execute('route', 'add', 'default', 'gw', gateway,
- run_as_root=True, check_exit_code=[0, 7])
+
+ for fields in old_routes:
+ _execute('ip', 'route', 'add', *fields,
+ run_as_root=True)
if FLAGS.send_arp_for_ha:
_execute('arping', '-U', network_ref['dhcp_server'],
'-A', '-I', dev,
@@ -1030,16 +1033,16 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
# NOTE(vish): This will break if there is already an ip on the
# interface, so we move any ips to the bridge
- old_gateway = None
- out, err = _execute('route', '-n', run_as_root=True)
+ # NOTE(danms): We also need to copy routes to the bridge so as
+ # not to break existing connectivity on the interface
+ old_routes = []
+ out, err = _execute('ip', 'route', 'show', 'dev', interface)
for line in out.split('\n'):
fields = line.split()
- if (fields and fields[0] == '0.0.0.0' and
- fields[-1] == interface):
- old_gateway = fields[1]
- _execute('route', 'del', 'default', 'gw', old_gateway,
- 'dev', interface, run_as_root=True,
- check_exit_code=[0, 7])
+ if fields and 'via' in fields:
+ old_routes.append(fields)
+ _execute('ip', 'route', 'del', *fields,
+ run_as_root=True)
out, err = _execute('ip', 'addr', 'show', 'dev', interface,
'scope', 'global', run_as_root=True)
for line in out.split('\n'):
@@ -1050,9 +1053,9 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
run_as_root=True, check_exit_code=[0, 2, 254])
_execute(*_ip_bridge_cmd('add', params, bridge),
run_as_root=True, check_exit_code=[0, 2, 254])
- if old_gateway:
- _execute('route', 'add', 'default', 'gw', old_gateway,
- run_as_root=True, check_exit_code=[0, 7])
+ for fields in old_routes:
+ _execute('ip', 'route', 'add', *fields,
+ run_as_root=True)
if (err and err != "device %s is already a member of a bridge;"
"can't enslave it to bridge %s.\n" % (interface, bridge)):
diff --git a/nova/tests/network/test_linux_net.py b/nova/tests/network/test_linux_net.py
index 4b60b624a..0660bb0f3 100644
--- a/nova/tests/network/test_linux_net.py
+++ b/nova/tests/network/test_linux_net.py
@@ -409,7 +409,7 @@ class LinuxNetworkTestCase(test.TestCase):
executes.append(args)
if args[0] == 'ip' and args[1] == 'addr' and args[2] == 'show':
return existing, ""
- if args[0] == 'route' and args[1] == '-n':
+ if args[0] == 'ip' and args[1] == 'route' and args[2] == 'show':
return routes, ""
self.stubs.Set(utils, 'execute', fake_execute)
network = {'dhcp_server': '192.168.1.1',
@@ -429,7 +429,7 @@ class LinuxNetworkTestCase(test.TestCase):
expected = [
('sysctl', '-w', 'net.ipv4.ip_forward=1'),
('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
- ('route', '-n'),
+ ('ip', 'route', 'show', 'dev', 'eth0'),
('ip', 'addr', 'del', '192.168.0.1/24',
'brd', '192.168.0.255', 'scope', 'global', 'dev', 'eth0'),
('ip', 'addr', 'add', '192.168.1.1/24',
@@ -442,8 +442,8 @@ class LinuxNetworkTestCase(test.TestCase):
self._test_initialize_gateway(existing, expected)
def test_initialize_gateway_resets_route(self):
- routes = ("0.0.0.0 192.68.0.1 0.0.0.0 "
- "UG 100 0 0 eth0")
+ routes = ("default via 192.168.0.1 dev eth0\n"
+ "192.168.100.0/24 via 192.168.0.254 dev eth0 proto static\n")
existing = ("2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> "
" mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n"
" link/ether de:ad:be:ef:be:ef brd ff:ff:ff:ff:ff:ff\n"
@@ -453,15 +453,19 @@ class LinuxNetworkTestCase(test.TestCase):
expected = [
('sysctl', '-w', 'net.ipv4.ip_forward=1'),
('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
- ('route', '-n'),
- ('route', 'del', 'default', 'gw', '192.68.0.1', 'dev', 'eth0'),
+ ('ip', 'route', 'show', 'dev', 'eth0'),
+ ('ip', 'route', 'del', 'default', 'dev', 'eth0'),
+ ('ip', 'route', 'del', '192.168.100.0/24', 'dev', 'eth0'),
('ip', 'addr', 'del', '192.168.0.1/24',
'brd', '192.168.0.255', 'scope', 'global', 'dev', 'eth0'),
('ip', 'addr', 'add', '192.168.1.1/24',
'brd', '192.168.1.255', 'dev', 'eth0'),
('ip', 'addr', 'add', '192.168.0.1/24',
'brd', '192.168.0.255', 'scope', 'global', 'dev', 'eth0'),
- ('route', 'add', 'default', 'gw', '192.68.0.1'),
+ ('ip', 'route', 'add', 'default', 'via', '192.168.0.1',
+ 'dev', 'eth0'),
+ ('ip', 'route', 'add', '192.168.100.0/24', 'via', '192.168.0.254',
+ 'dev', 'eth0', 'proto', 'static'),
('ip', '-f', 'inet6', 'addr', 'change',
'2001:db8::/64', 'dev', 'eth0'),
]
@@ -492,7 +496,7 @@ class LinuxNetworkTestCase(test.TestCase):
expected = [
('sysctl', '-w', 'net.ipv4.ip_forward=1'),
('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
- ('route', '-n'),
+ ('ip', 'route', 'show', 'dev', 'eth0'),
('ip', 'addr', 'add', '192.168.1.1/24',
'brd', '192.168.1.255', 'dev', 'eth0'),
('ip', '-f', 'inet6', 'addr', 'change',