diff options
| author | Dan Smith <danms@us.ibm.com> | 2012-06-22 10:15:42 -0700 |
|---|---|---|
| committer | Dan Smith <danms@us.ibm.com> | 2012-06-25 13:17:23 -0700 |
| commit | 76a7a3540b3e2f111c267df83fb0b528dd8c6fa5 (patch) | |
| tree | acdded8bc48abc09edaf119338b89d49485db7e3 | |
| parent | ad6b11c17c8afd6522d9e9dce269e3f51b5b0851 (diff) | |
| download | nova-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-- | Authors | 1 | ||||
| -rw-r--r-- | etc/nova/rootwrap.d/compute.filters | 11 | ||||
| -rw-r--r-- | etc/nova/rootwrap.d/network.filters | 11 | ||||
| -rw-r--r-- | nova/network/linux_net.py | 49 | ||||
| -rw-r--r-- | nova/tests/network/test_linux_net.py | 20 |
5 files changed, 45 insertions, 47 deletions
@@ -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', |
