Sophie

Sophie

distrib > Fedora > 16 > i386 > by-pkgid > 5c655bb31b7eacedb96e8b5da992c6ce > files > 4

openstack-nova-2011.3.1-11.fc16.src.rpm

From d064c4460b8719ac3fda3d8e369fa5dc77ac6ec4 Mon Sep 17 00:00:00 2001
From: Vishvananda Ishaya <vishvananda@gmail.com>
Date: Thu, 2 Feb 2012 10:59:43 -0800
Subject: [PATCH] Provides flag override for vlan interface

This means you can have your vlan_interface be different on
different hosts machines by setting vlan_interface differently
on each host.

 * Allow non-homogenous vlan networks
 * Fixes bug 833426
 * Includes failing test for linux_net

(cherry picked from commit 8efe15209aaee6b15c8edb21362c08137294a7de)

Resolved Conflicts:

	nova/tests/test_linux_net.py

Change-Id: I68aa52e745318cedfbefb6fbac8187fceb1ae06b
---
 nova/network/linux_net.py    |    3 +-
 nova/tests/test_linux_net.py | 1019 +++++++++++++++++++++++-------------------
 nova/virt/libvirt/vif.py     |    3 +-
 nova/virt/xenapi/vif.py      |    2 +-
 4 files changed, 562 insertions(+), 465 deletions(-)

diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index a6aea8a..67c2f37 100755
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -864,10 +864,11 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
 
     def plug(self, network, mac_address):
         if network.get('vlan', None) is not None:
+            iface = FLAGS.vlan_interface or network['bridge_interface']
             LinuxBridgeInterfaceDriver.ensure_vlan_bridge(
                            network['vlan'],
                            network['bridge'],
-                           network['bridge_interface'],
+                           iface,
                            network,
                            mac_address)
         else:
diff --git a/nova/tests/test_linux_net.py b/nova/tests/test_linux_net.py
index 0f5862f..f81bb0c 100755
--- a/nova/tests/test_linux_net.py
+++ b/nova/tests/test_linux_net.py
@@ -1,462 +1,557 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 NTT
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mox
-
-from nova import db
-from nova import flags
-from nova import log as logging
-from nova import test
-from nova import utils
-from nova.network import linux_net
-
-
-FLAGS = flags.FLAGS
-
-LOG = logging.getLogger('nova.tests.network')
-
-
-HOST = "testhost"
-
-instances = [{'id': 0,
-              'host': 'fake_instance00',
-              'hostname': 'fake_instance00'},
-             {'id': 1,
-              'host': 'fake_instance01',
-              'hostname': 'fake_instance01'}]
-
-
-addresses = [{"address": "10.0.0.1"},
-             {"address": "10.0.0.2"},
-             {"address": "10.0.0.3"},
-             {"address": "10.0.0.4"},
-             {"address": "10.0.0.5"},
-             {"address": "10.0.0.6"}]
-
-
-networks = [{'id': 0,
-             'uuid': "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
-             'label': 'test0',
-             'injected': False,
-             'multi_host': False,
-             'cidr': '192.168.0.0/24',
-             'cidr_v6': '2001:db8::/64',
-             'gateway_v6': '2001:db8::1',
-             'netmask_v6': '64',
-             'netmask': '255.255.255.0',
-             'bridge': 'fa0',
-             'bridge_interface': 'fake_fa0',
-             'gateway': '192.168.0.1',
-             'broadcast': '192.168.0.255',
-             'dns1': '192.168.0.1',
-             'dns2': '192.168.0.2',
-             'dhcp_server': '0.0.0.0',
-             'dhcp_start': '192.168.100.1',
-             'vlan': None,
-             'host': None,
-             'project_id': 'fake_project',
-             'vpn_public_address': '192.168.0.2'},
-            {'id': 1,
-             'uuid': "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
-             'label': 'test1',
-             'injected': False,
-             'multi_host': False,
-             'cidr': '192.168.1.0/24',
-             'cidr_v6': '2001:db9::/64',
-             'gateway_v6': '2001:db9::1',
-             'netmask_v6': '64',
-             'netmask': '255.255.255.0',
-             'bridge': 'fa1',
-             'bridge_interface': 'fake_fa1',
-             'gateway': '192.168.1.1',
-             'broadcast': '192.168.1.255',
-             'dns1': '192.168.0.1',
-             'dns2': '192.168.0.2',
-             'dhcp_server': '0.0.0.0',
-             'dhcp_start': '192.168.100.1',
-             'vlan': None,
-             'host': None,
-             'project_id': 'fake_project',
-             'vpn_public_address': '192.168.1.2'}]
-
-
-fixed_ips = [{'id': 0,
-              'network_id': 0,
-              'address': '192.168.0.100',
-              'instance_id': 0,
-              'allocated': True,
-              'virtual_interface_id': 0,
-              'virtual_interface': addresses[0],
-              'instance': instances[0],
-              'floating_ips': []},
-             {'id': 1,
-              'network_id': 1,
-              'address': '192.168.1.100',
-              'instance_id': 0,
-              'allocated': True,
-              'virtual_interface_id': 1,
-              'virtual_interface': addresses[1],
-              'instance': instances[0],
-              'floating_ips': []},
-             {'id': 2,
-              'network_id': 1,
-              'address': '192.168.0.101',
-              'instance_id': 1,
-              'allocated': True,
-              'virtual_interface_id': 2,
-              'virtual_interface': addresses[2],
-              'instance': instances[1],
-              'floating_ips': []},
-             {'id': 3,
-              'network_id': 0,
-              'address': '192.168.1.101',
-              'instance_id': 1,
-              'allocated': True,
-              'virtual_interface_id': 3,
-              'virtual_interface': addresses[3],
-              'instance': instances[1],
-              'floating_ips': []},
-             {'id': 4,
-              'network_id': 0,
-              'address': '192.168.0.102',
-              'instance_id': 0,
-              'allocated': True,
-              'virtual_interface_id': 4,
-              'virtual_interface': addresses[4],
-              'instance': instances[0],
-              'floating_ips': []},
-             {'id': 5,
-              'network_id': 1,
-              'address': '192.168.1.102',
-              'instance_id': 1,
-              'allocated': True,
-              'virtual_interface_id': 5,
-              'virtual_interface': addresses[5],
-              'instance': instances[1],
-              'floating_ips': []}]
-
-
-vifs = [{'id': 0,
-         'address': 'DE:AD:BE:EF:00:00',
-         'uuid': '00000000-0000-0000-0000-0000000000000000',
-         'network_id': 0,
-         'network': networks[0],
-         'instance_id': 0},
-        {'id': 1,
-         'address': 'DE:AD:BE:EF:00:01',
-         'uuid': '00000000-0000-0000-0000-0000000000000001',
-         'network_id': 1,
-         'network': networks[1],
-         'instance_id': 0},
-        {'id': 2,
-         'address': 'DE:AD:BE:EF:00:02',
-         'uuid': '00000000-0000-0000-0000-0000000000000002',
-         'network_id': 1,
-         'network': networks[1],
-         'instance_id': 1},
-        {'id': 3,
-         'address': 'DE:AD:BE:EF:00:03',
-         'uuid': '00000000-0000-0000-0000-0000000000000003',
-         'network_id': 0,
-         'network': networks[0],
-         'instance_id': 1},
-        {'id': 4,
-         'address': 'DE:AD:BE:EF:00:04',
-         'uuid': '00000000-0000-0000-0000-0000000000000004',
-         'network_id': 0,
-         'network': networks[0],
-         'instance_id': 0},
-        {'id': 5,
-         'address': 'DE:AD:BE:EF:00:05',
-         'uuid': '00000000-0000-0000-0000-0000000000000005',
-         'network_id': 1,
-         'network': networks[1],
-         'instance_id': 1}]
-
-
-class LinuxNetworkTestCase(test.TestCase):
-
-    def setUp(self):
-        super(LinuxNetworkTestCase, self).setUp()
-        network_driver = FLAGS.network_driver
-        self.driver = utils.import_object(network_driver)
-        self.driver.db = db
-
-    def test_update_dhcp_for_nw00(self):
-        self.flags(use_single_default_gateway=True)
-        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
-        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[0],
-                                                        fixed_ips[3]])
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[0],
-                                                        fixed_ips[3]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[0], vifs[1]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[2], vifs[3]])
-        self.mox.ReplayAll()
-
-        self.driver.update_dhcp(None, "eth0", networks[0])
-
-    def test_update_dhcp_for_nw01(self):
-        self.flags(use_single_default_gateway=True)
-        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
-        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[1],
-                                                        fixed_ips[2]])
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[1],
-                                                        fixed_ips[2]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[0], vifs[1]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[2], vifs[3]])
-        self.mox.ReplayAll()
-
-        self.driver.update_dhcp(None, "eth0", networks[0])
-
-    def test_get_dhcp_hosts_for_nw00(self):
-        self.flags(use_single_default_gateway=True)
-        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[0],
-                                                        fixed_ips[3]])
-        self.mox.ReplayAll()
-
-        expected = \
-        "10.0.0.1,fake_instance00.novalocal,"\
-            "192.168.0.100,net:NW-i00000000-0\n"\
-        "10.0.0.4,fake_instance01.novalocal,"\
-            "192.168.1.101,net:NW-i00000001-0"
-        actual_hosts = self.driver.get_dhcp_hosts(None, networks[1])
-
-        self.assertEquals(actual_hosts, expected)
-
-    def test_get_dhcp_hosts_for_nw01(self):
-        self.flags(use_single_default_gateway=True)
-        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[1],
-                                                        fixed_ips[2]])
-        self.mox.ReplayAll()
-
-        expected = \
-        "10.0.0.2,fake_instance00.novalocal,"\
-            "192.168.1.100,net:NW-i00000000-1\n"\
-        "10.0.0.3,fake_instance01.novalocal,"\
-            "192.168.0.101,net:NW-i00000001-1"
-        actual_hosts = self.driver.get_dhcp_hosts(None, networks[0])
-
-        self.assertEquals(actual_hosts, expected)
-
-    def test_get_dhcp_opts_for_nw00(self):
-        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
-        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[0],
-                                                        fixed_ips[3],
-                                                        fixed_ips[4]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[0],
-                                                         vifs[1],
-                                                         vifs[4]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[2],
-                                                         vifs[3],
-                                                         vifs[5]])
-        self.mox.ReplayAll()
-
-        expected_opts = 'NW-i00000001-0,3'
-        actual_opts = self.driver.get_dhcp_opts(None, networks[0])
-
-        self.assertEquals(actual_opts, expected_opts)
-
-    def test_get_dhcp_opts_for_nw01(self):
-        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
-        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
-
-        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
-                                            mox.IgnoreArg())\
-                                            .AndReturn([fixed_ips[1],
-                                                        fixed_ips[2],
-                                                        fixed_ips[5]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[0],
-                                                         vifs[1],
-                                                         vifs[4]])
-        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
-                                             mox.IgnoreArg())\
-                                             .AndReturn([vifs[2],
-                                                         vifs[3],
-                                                         vifs[5]])
-        self.mox.ReplayAll()
-
-        expected_opts = "NW-i00000000-1,3"
-        actual_opts = self.driver.get_dhcp_opts(None, networks[1])
-
-        self.assertEquals(actual_opts, expected_opts)
-
-    def test_dhcp_opts_not_default_gateway_network(self):
-        expected = "NW-i00000000-0,3"
-        actual = self.driver._host_dhcp_opts(fixed_ips[0])
-        self.assertEquals(actual, expected)
-
-    def test_host_dhcp_without_default_gateway_network(self):
-        expected = ("10.0.0.1,fake_instance00.novalocal,192.168.0.100")
-        actual = self.driver._host_dhcp(fixed_ips[0])
-        self.assertEquals(actual, expected)
-
-    def test_linux_bridge_driver_plug(self):
-        """Makes sure plug doesn't drop FORWARD by default.
-
-        Ensures bug 890195 doesn't reappear."""
-
-        def fake_execute(*args, **kwargs):
-            return "", ""
-        self.stubs.Set(utils, 'execute', fake_execute)
-
-        def verify_add_rule(chain, rule):
-            self.assertEqual(chain, 'FORWARD')
-            self.assertIn('ACCEPT', rule)
-        self.stubs.Set(linux_net.iptables_manager.ipv4['filter'],
-                       'add_rule', verify_add_rule)
-        driver = linux_net.LinuxBridgeInterfaceDriver()
-        driver.plug({"bridge": "br100", "bridge_interface": "eth0"},
-                    "fakemac")
-
-    def _test_initialize_gateway(self, existing, expected, routes=''):
-        self.flags(fake_network=False)
-        executes = []
-
-        def fake_execute(*args, **kwargs):
-            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':
-                return routes, ""
-        self.stubs.Set(utils, 'execute', fake_execute)
-        network = {'dhcp_server': '192.168.1.1',
-                   'cidr': '192.168.1.0/24',
-                   'broadcast': '192.168.1.255',
-                   'cidr_v6': '2001:db8::/64'}
-        self.driver.initialize_gateway_device('eth0', network)
-        self.assertEqual(executes, expected)
-
-    def test_initialize_gateway_moves_wrong_ip(self):
-        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"
-            "    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
-            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
-            "    valid_lft forever preferred_lft forever\n")
-        expected = [
-            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
-            ('route', '-n'),
-            ('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'),
-            ('ip', '-f', 'inet6', 'addr', 'change',
-             '2001:db8::/64', 'dev', 'eth0'),
-            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
-        ]
-        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"
-        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"
-            "    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
-            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
-            "    valid_lft forever preferred_lft forever\n")
-        expected = [
-            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
-            ('route', '-n'),
-            ('route', 'del', 'default', 'gw', '192.68.0.1', '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', '-f', 'inet6', 'addr', 'change',
-             '2001:db8::/64', 'dev', 'eth0'),
-            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
-        ]
-        self._test_initialize_gateway(existing, expected, routes)
-
-    def test_initialize_gateway_no_move_right_ip(self):
-        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"
-            "    inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0\n"
-            "    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
-            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
-            "    valid_lft forever preferred_lft forever\n")
-        expected = [
-            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
-            ('ip', '-f', 'inet6', 'addr', 'change',
-             '2001:db8::/64', 'dev', 'eth0'),
-            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
-        ]
-        self._test_initialize_gateway(existing, expected)
-
-    def test_initialize_gateway_add_if_blank(self):
-        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"
-            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
-            "    valid_lft forever preferred_lft forever\n")
-        expected = [
-            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
-            ('route', '-n'),
-            ('ip', 'addr', 'add', '192.168.1.1/24',
-             'brd', '192.168.1.255', 'dev', 'eth0'),
-            ('ip', '-f', 'inet6', 'addr', 'change',
-             '2001:db8::/64', 'dev', 'eth0'),
-            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
-        ]
-        self._test_initialize_gateway(existing, expected)
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 NTT
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import os
+
+import mox
+
+from nova import context
+from nova import db
+from nova import flags
+from nova import log as logging
+from nova import test
+from nova import utils
+from nova.network import linux_net
+
+
+FLAGS = flags.FLAGS
+
+LOG = logging.getLogger('nova.tests.network')
+
+
+HOST = "testhost"
+
+instances = [{'id': 0,
+              'host': 'fake_instance00',
+              'hostname': 'fake_instance00'},
+             {'id': 1,
+              'host': 'fake_instance01',
+              'hostname': 'fake_instance01'}]
+
+
+addresses = [{"address": "10.0.0.1"},
+             {"address": "10.0.0.2"},
+             {"address": "10.0.0.3"},
+             {"address": "10.0.0.4"},
+             {"address": "10.0.0.5"},
+             {"address": "10.0.0.6"}]
+
+
+networks = [{'id': 0,
+             'uuid': "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
+             'label': 'test0',
+             'injected': False,
+             'multi_host': False,
+             'cidr': '192.168.0.0/24',
+             'cidr_v6': '2001:db8::/64',
+             'gateway_v6': '2001:db8::1',
+             'netmask_v6': '64',
+             'netmask': '255.255.255.0',
+             'bridge': 'fa0',
+             'bridge_interface': 'fake_fa0',
+             'gateway': '192.168.0.1',
+             'broadcast': '192.168.0.255',
+             'dns1': '192.168.0.1',
+             'dns2': '192.168.0.2',
+             'dhcp_server': '0.0.0.0',
+             'dhcp_start': '192.168.100.1',
+             'vlan': None,
+             'host': None,
+             'project_id': 'fake_project',
+             'vpn_public_address': '192.168.0.2'},
+            {'id': 1,
+             'uuid': "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
+             'label': 'test1',
+             'injected': False,
+             'multi_host': False,
+             'cidr': '192.168.1.0/24',
+             'cidr_v6': '2001:db9::/64',
+             'gateway_v6': '2001:db9::1',
+             'netmask_v6': '64',
+             'netmask': '255.255.255.0',
+             'bridge': 'fa1',
+             'bridge_interface': 'fake_fa1',
+             'gateway': '192.168.1.1',
+             'broadcast': '192.168.1.255',
+             'dns1': '192.168.0.1',
+             'dns2': '192.168.0.2',
+             'dhcp_server': '0.0.0.0',
+             'dhcp_start': '192.168.100.1',
+             'vlan': None,
+             'host': None,
+             'project_id': 'fake_project',
+             'vpn_public_address': '192.168.1.2'}]
+
+
+fixed_ips = [{'id': 0,
+              'network_id': 0,
+              'address': '192.168.0.100',
+              'instance_id': 0,
+              'allocated': True,
+              'virtual_interface_id': 0,
+              'instance_id': 0,
+              'floating_ips': []},
+             {'id': 1,
+              'network_id': 1,
+              'address': '192.168.1.100',
+              'instance_id': 0,
+              'allocated': True,
+              'virtual_interface_id': 1,
+              'instance_id': 0,
+              'floating_ips': []},
+             {'id': 2,
+              'network_id': 1,
+              'address': '192.168.0.101',
+              'instance_id': 1,
+              'allocated': True,
+              'virtual_interface_id': 2,
+              'instance_id': 1,
+              'floating_ips': []},
+             {'id': 3,
+              'network_id': 0,
+              'address': '192.168.1.101',
+              'instance_id': 1,
+              'allocated': True,
+              'virtual_interface_id': 3,
+              'instance_id': 1,
+              'floating_ips': []},
+             {'id': 4,
+              'network_id': 0,
+              'address': '192.168.0.102',
+              'instance_id': 0,
+              'allocated': True,
+              'virtual_interface_id': 4,
+              'instance_id': 0,
+              'floating_ips': []},
+             {'id': 5,
+              'network_id': 1,
+              'address': '192.168.1.102',
+              'instance_id': 1,
+              'allocated': True,
+              'virtual_interface_id': 5,
+              'instance_id': 1,
+              'floating_ips': []}]
+
+
+vifs = [{'id': 0,
+         'address': 'DE:AD:BE:EF:00:00',
+         'uuid': '00000000-0000-0000-0000-0000000000000000',
+         'network_id': 0,
+         'instance_id': 0},
+        {'id': 1,
+         'address': 'DE:AD:BE:EF:00:01',
+         'uuid': '00000000-0000-0000-0000-0000000000000001',
+         'network_id': 1,
+         'instance_id': 0},
+        {'id': 2,
+         'address': 'DE:AD:BE:EF:00:02',
+         'uuid': '00000000-0000-0000-0000-0000000000000002',
+         'network_id': 1,
+         'instance_id': 1},
+        {'id': 3,
+         'address': 'DE:AD:BE:EF:00:03',
+         'uuid': '00000000-0000-0000-0000-0000000000000003',
+         'network_id': 0,
+         'instance_id': 1},
+        {'id': 4,
+         'address': 'DE:AD:BE:EF:00:04',
+         'uuid': '00000000-0000-0000-0000-0000000000000004',
+         'network_id': 0,
+         'instance_id': 0},
+        {'id': 5,
+         'address': 'DE:AD:BE:EF:00:05',
+         'uuid': '00000000-0000-0000-0000-0000000000000005',
+         'network_id': 1,
+         'instance_id': 1}]
+
+
+class LinuxNetworkTestCase(test.TestCase):
+
+    def setUp(self):
+        super(LinuxNetworkTestCase, self).setUp()
+        network_driver = FLAGS.network_driver
+        self.driver = utils.import_object(network_driver)
+        self.driver.db = db
+        self.context = context.RequestContext('testuser', 'testproject',
+                                              is_admin=True)
+
+    def test_update_dhcp_for_nw00(self):
+        self.flags(use_single_default_gateway=True)
+
+        def get_vif(_context, vif_id):
+            return vifs[vif_id]
+
+        def get_instance(_context, instance_id):
+            return instances[instance_id]
+
+        self.stubs.Set(db, 'virtual_interface_get', get_vif)
+        self.stubs.Set(db, 'instance_get', get_instance)
+        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
+        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
+        self.mox.StubOutWithMock(self.driver, 'write_to_file')
+        self.mox.StubOutWithMock(self.driver, 'ensure_path')
+        self.mox.StubOutWithMock(os, 'chmod')
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[0],
+                                                        fixed_ips[3]])
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[0],
+                                                        fixed_ips[3]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[0], vifs[1]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[2], vifs[3]])
+        self.driver.write_to_file(mox.IgnoreArg(), mox.IgnoreArg())
+        self.driver.write_to_file(mox.IgnoreArg(), mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        os.chmod(mox.IgnoreArg(), mox.IgnoreArg())
+        os.chmod(mox.IgnoreArg(), mox.IgnoreArg())
+
+        self.mox.ReplayAll()
+
+        self.driver.update_dhcp(self.context, "eth0", networks[0])
+
+    def test_update_dhcp_for_nw01(self):
+        self.flags(use_single_default_gateway=True)
+
+        def get_vif(_context, vif_id):
+            return vifs[vif_id]
+
+        def get_instance(_context, instance_id):
+            return instances[instance_id]
+
+        self.stubs.Set(db, 'virtual_interface_get', get_vif)
+        self.stubs.Set(db, 'instance_get', get_instance)
+        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
+        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
+        self.mox.StubOutWithMock(self.driver, 'write_to_file')
+        self.mox.StubOutWithMock(self.driver, 'ensure_path')
+        self.mox.StubOutWithMock(os, 'chmod')
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[1],
+                                                        fixed_ips[2]])
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[1],
+                                                        fixed_ips[2]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[0], vifs[1]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[2], vifs[3]])
+        self.driver.write_to_file(mox.IgnoreArg(), mox.IgnoreArg())
+        self.driver.write_to_file(mox.IgnoreArg(), mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        self.driver.ensure_path(mox.IgnoreArg())
+        os.chmod(mox.IgnoreArg(), mox.IgnoreArg())
+        os.chmod(mox.IgnoreArg(), mox.IgnoreArg())
+
+        self.mox.ReplayAll()
+
+        self.driver.update_dhcp(self.context, "eth0", networks[0])
+
+    def test_get_dhcp_hosts_for_nw00(self):
+        self.flags(use_single_default_gateway=True)
+
+        def get_vif(_context, vif_id):
+            return vifs[vif_id]
+
+        def get_instance(_context, instance_id):
+            return instances[instance_id]
+
+        self.stubs.Set(db, 'virtual_interface_get', get_vif)
+        self.stubs.Set(db, 'instance_get', get_instance)
+        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[0],
+                                                        fixed_ips[3]])
+        self.mox.ReplayAll()
+
+        expected = \
+        "DE:AD:BE:EF:00:00,fake_instance00.novalocal,"\
+            "192.168.0.100,net:NW-i00000000-0\n"\
+        "DE:AD:BE:EF:00:03,fake_instance01.novalocal,"\
+            "192.168.1.101,net:NW-i00000001-0"
+        actual_hosts = self.driver.get_dhcp_hosts(self.context, networks[1])
+
+        self.assertEquals(actual_hosts, expected)
+
+    def test_get_dhcp_hosts_for_nw01(self):
+        self.flags(use_single_default_gateway=True)
+
+        def get_vif(_context, vif_id):
+            return vifs[vif_id]
+
+        def get_instance(_context, instance_id):
+            return instances[instance_id]
+
+        self.stubs.Set(db, 'virtual_interface_get', get_vif)
+        self.stubs.Set(db, 'instance_get', get_instance)
+        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[1],
+                                                        fixed_ips[2]])
+        self.mox.ReplayAll()
+
+        expected = \
+        "DE:AD:BE:EF:00:01,fake_instance00.novalocal,"\
+            "192.168.1.100,net:NW-i00000000-1\n"\
+        "DE:AD:BE:EF:00:02,fake_instance01.novalocal,"\
+            "192.168.0.101,net:NW-i00000001-1"
+        actual_hosts = self.driver.get_dhcp_hosts(self.context, networks[0])
+
+        self.assertEquals(actual_hosts, expected)
+
+    def test_get_dhcp_opts_for_nw00(self):
+        def get_instance(_context, instance_id):
+            return instances[instance_id]
+
+        self.stubs.Set(db, 'instance_get', get_instance)
+        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
+        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[0],
+                                                        fixed_ips[3],
+                                                        fixed_ips[4]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[0],
+                                                         vifs[1],
+                                                         vifs[4]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[2],
+                                                         vifs[3],
+                                                         vifs[5]])
+        self.mox.ReplayAll()
+
+        expected_opts = 'NW-i00000001-0,3'
+        actual_opts = self.driver.get_dhcp_opts(self.context, networks[0])
+
+        self.assertEquals(actual_opts, expected_opts)
+
+    def test_get_dhcp_opts_for_nw01(self):
+        def get_instance(_context, instance_id):
+            print instance_id
+            return instances[instance_id]
+
+        self.stubs.Set(db, 'instance_get', get_instance)
+        self.mox.StubOutWithMock(db, 'network_get_associated_fixed_ips')
+        self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
+
+        db.network_get_associated_fixed_ips(mox.IgnoreArg(),
+                                            mox.IgnoreArg())\
+                                            .AndReturn([fixed_ips[1],
+                                                        fixed_ips[2],
+                                                        fixed_ips[5]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[0],
+                                                         vifs[1],
+                                                         vifs[4]])
+        db.virtual_interface_get_by_instance(mox.IgnoreArg(),
+                                             mox.IgnoreArg())\
+                                             .AndReturn([vifs[2],
+                                                         vifs[3],
+                                                         vifs[5]])
+        self.mox.ReplayAll()
+
+        expected_opts = "NW-i00000000-1,3"
+        actual_opts = self.driver.get_dhcp_opts(self.context, networks[1])
+
+        self.assertEquals(actual_opts, expected_opts)
+
+    def test_dhcp_opts_not_default_gateway_network(self):
+        expected = "NW-i00000000-0,3"
+        actual = self.driver._host_dhcp_opts(fixed_ips[0], instances[0])
+        self.assertEquals(actual, expected)
+
+    def test_host_dhcp_without_default_gateway_network(self):
+        expected = ','.join(['DE:AD:BE:EF:00:00',
+                             'fake_instance00.novalocal',
+                             '192.168.0.100'])
+        actual = self.driver._host_dhcp(fixed_ips[0], vifs[0], instances[0])
+        self.assertEquals(actual, expected)
+
+    def test_linux_bridge_driver_plug(self):
+        """Makes sure plug doesn't drop FORWARD by default.
+
+        Ensures bug 890195 doesn't reappear."""
+
+        def fake_execute(*args, **kwargs):
+            return "", ""
+        self.stubs.Set(utils, 'execute', fake_execute)
+
+        def verify_add_rule(chain, rule):
+            self.assertEqual(chain, 'FORWARD')
+            self.assertIn('ACCEPT', rule)
+        self.stubs.Set(linux_net.iptables_manager.ipv4['filter'],
+                       'add_rule', verify_add_rule)
+        driver = linux_net.LinuxBridgeInterfaceDriver()
+        driver.plug({"bridge": "br100", "bridge_interface": "eth0"},
+                    "fakemac")
+
+    def test_vlan_override(self):
+        """Makes sure vlan_interface flag overrides network bridge_interface.
+
+        Allows heterogeneous networks a la bug 833426"""
+
+        driver = linux_net.LinuxBridgeInterfaceDriver()
+
+        @classmethod
+        def test_ensure(_self, vlan, bridge, interface, network, mac_address):
+            self.passed_interface = interface
+
+        self.stubs.Set(linux_net.LinuxBridgeInterfaceDriver,
+                       'ensure_vlan_bridge', test_ensure)
+
+        network = {
+                "bridge": "br100",
+                "bridge_interface": "base_interface",
+                "vlan": "fake"
+        }
+        driver.plug(network, "fakemac")
+        self.assertEqual(self.passed_interface, "base_interface")
+        self.flags(vlan_interface="override_interface")
+        driver.plug(network, "fakemac")
+        self.assertEqual(self.passed_interface, "override_interface")
+
+    def _test_initialize_gateway(self, existing, expected, routes=''):
+        self.flags(fake_network=False)
+        executes = []
+
+        def fake_execute(*args, **kwargs):
+            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':
+                return routes, ""
+        self.stubs.Set(utils, 'execute', fake_execute)
+        network = {'dhcp_server': '192.168.1.1',
+                   'cidr': '192.168.1.0/24',
+                   'broadcast': '192.168.1.255',
+                   'cidr_v6': '2001:db8::/64'}
+        self.driver.initialize_gateway_device('eth0', network)
+        self.assertEqual(executes, expected)
+
+    def test_initialize_gateway_moves_wrong_ip(self):
+        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"
+            "    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
+            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
+            "    valid_lft forever preferred_lft forever\n")
+        expected = [
+            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
+            ('route', '-n'),
+            ('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'),
+            ('ip', '-f', 'inet6', 'addr', 'change',
+             '2001:db8::/64', 'dev', 'eth0'),
+            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
+        ]
+        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"
+        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"
+            "    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
+            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
+            "    valid_lft forever preferred_lft forever\n")
+        expected = [
+            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
+            ('route', '-n'),
+            ('route', 'del', 'default', 'gw', '192.68.0.1', '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', '-f', 'inet6', 'addr', 'change',
+             '2001:db8::/64', 'dev', 'eth0'),
+            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
+        ]
+        self._test_initialize_gateway(existing, expected, routes)
+
+    def test_initialize_gateway_no_move_right_ip(self):
+        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"
+            "    inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0\n"
+            "    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
+            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
+            "    valid_lft forever preferred_lft forever\n")
+        expected = [
+            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
+            ('ip', '-f', 'inet6', 'addr', 'change',
+             '2001:db8::/64', 'dev', 'eth0'),
+            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
+        ]
+        self._test_initialize_gateway(existing, expected)
+
+    def test_initialize_gateway_add_if_blank(self):
+        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"
+            "    inet6 dead::beef:dead:beef:dead/64 scope link\n"
+            "    valid_lft forever preferred_lft forever\n")
+        expected = [
+            ('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
+            ('route', '-n'),
+            ('ip', 'addr', 'add', '192.168.1.1/24',
+             'brd', '192.168.1.255', 'dev', 'eth0'),
+            ('ip', '-f', 'inet6', 'addr', 'change',
+             '2001:db8::/64', 'dev', 'eth0'),
+            ('ip', 'link', 'set', 'dev', 'eth0', 'promisc', 'on'),
+        ]
+        self._test_initialize_gateway(existing, expected)
diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py
index fdfae38..aee2a8a 100644
--- a/nova/virt/libvirt/vif.py
+++ b/nova/virt/libvirt/vif.py
@@ -77,13 +77,14 @@ class LibvirtBridgeDriver(VIFDriver):
         if (not network.get('multi_host') and
             mapping.get('should_create_bridge')):
             if mapping.get('should_create_vlan'):
+                iface = FLAGS.vlan_interface or network['bridge_interface']
                 LOG.debug(_('Ensuring vlan %(vlan)s and bridge %(bridge)s'),
                           {'vlan': network['vlan'],
                            'bridge': network['bridge']})
                 linux_net.LinuxBridgeInterfaceDriver.ensure_vlan_bridge(
                                              network['vlan'],
                                              network['bridge'],
-                                             network['bridge_interface'])
+                                             iface)
             else:
                 LOG.debug(_("Ensuring bridge %s"), network['bridge'])
                 linux_net.LinuxBridgeInterfaceDriver.ensure_bridge(
diff --git a/nova/virt/xenapi/vif.py b/nova/virt/xenapi/vif.py
index 2f25efe..11d5ade 100644
--- a/nova/virt/xenapi/vif.py
+++ b/nova/virt/xenapi/vif.py
@@ -59,7 +59,7 @@ class XenAPIBridgeDriver(VIFDriver):
 
         vlan_num = network['vlan']
         bridge = network['bridge']
-        bridge_interface = network['bridge_interface']
+        bridge_interface = FLAGS.vlan_interface or network['bridge_interface']
         # Check whether bridge already exists
         # Retrieve network whose name_label is "bridge"
         network_ref = NetworkHelper.find_network_with_name_label(