summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--Authors1
-rw-r--r--etc/nova/rootwrap.d/compute.filters11
-rw-r--r--etc/nova/rootwrap.d/network.filters11
-rw-r--r--nova/network/linux_net.py49
-rw-r--r--nova/tests/network/test_linux_net.py20
5 files changed, 45 insertions, 47 deletions
diff --git a/Authors b/Authors
index fb6f98e02..e1a1ee839 100644
--- a/Authors
+++ b/Authors
@@ -44,6 +44,7 @@ Cory Wright <corywright@gmail.com>
Craig Vyvial <cp16net@gmail.com>
Dan Prince <dprince@redhat.com>
Dan Wendlandt <dan@nicira.com>
+Dan Smith <danms@us.ibm.com>
Daniel P. Berrange <berrange@redhat.com>
Dave Lapsley <dlapsley@nicira.com>
Dave Walker <Dave.Walker@canonical.com>
diff --git a/etc/nova/rootwrap.d/compute.filters b/etc/nova/rootwrap.d/compute.filters
index c2e760f0e..fffeff85a 100644
--- a/etc/nova/rootwrap.d/compute.filters
+++ b/etc/nova/rootwrap.d/compute.filters
@@ -78,6 +78,9 @@ cp: CommandFilter, /bin/cp, root
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, ..
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
+# nova/network/linux_net.py: 'ip', 'route', 'add', ..
+# nova/network/linux_net.py: 'ip', 'route', 'del', .
+# nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev
ip: CommandFilter, /sbin/ip, root
# nova/virt/libvirt/vif.py: 'tunctl', '-b', '-t', dev
@@ -130,14 +133,6 @@ ip6tables-restore_usr: CommandFilter, /usr/sbin/ip6tables-restore, root
arping: CommandFilter, /usr/bin/arping, root
arping_sbin: CommandFilter, /sbin/arping, root
-# nova/network/linux_net.py: 'route', '-n'
-# nova/network/linux_net.py: 'route', 'del', 'default', 'gw'
-# nova/network/linux_net.py: 'route', 'add', 'default', 'gw'
-# nova/network/linux_net.py: 'route', '-n'
-# nova/network/linux_net.py: 'route', 'del', 'default', 'gw', old_gw, ..
-# nova/network/linux_net.py: 'route', 'add', 'default', 'gw', old_gateway
-route: CommandFilter, /sbin/route, root
-
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
dhcp_release: CommandFilter, /usr/bin/dhcp_release, root
diff --git a/etc/nova/rootwrap.d/network.filters b/etc/nova/rootwrap.d/network.filters
index c85ab9a33..c635f12e4 100644
--- a/etc/nova/rootwrap.d/network.filters
+++ b/etc/nova/rootwrap.d/network.filters
@@ -21,6 +21,9 @@
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, ..
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
+# nova/network/linux_net.py: 'ip', 'route', 'add', ..
+# nova/network/linux_net.py: 'ip', 'route', 'del', .
+# nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev
ip: CommandFilter, /sbin/ip, root
# nova/virt/libvirt/vif.py: 'ovs-vsctl', ...
@@ -48,14 +51,6 @@ ip6tables-restore_usr: CommandFilter, /usr/sbin/ip6tables-restore, root
arping: CommandFilter, /usr/bin/arping, root
arping_sbin: CommandFilter, /sbin/arping, root
-# nova/network/linux_net.py: 'route', '-n'
-# nova/network/linux_net.py: 'route', 'del', 'default', 'gw'
-# nova/network/linux_net.py: 'route', 'add', 'default', 'gw'
-# nova/network/linux_net.py: 'route', '-n'
-# nova/network/linux_net.py: 'route', 'del', 'default', 'gw', old_gw, ..
-# nova/network/linux_net.py: 'route', 'add', 'default', 'gw', old_gateway
-route: CommandFilter, /sbin/route, root
-
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
dhcp_release: CommandFilter, /usr/bin/dhcp_release, root
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',