From 0a00205c2a209f20a9d900ddb30f25628a32ebd9 Mon Sep 17 00:00:00 2001 From: Oleg Bondarev Date: Wed, 30 Dec 2015 20:24:55 +0300 Subject: [PATCH] Fix get_subnet_for_dvr() to return correct gateway mac Fix filters to get the right gateway port for a subnet. Wrong filters led to random port's mac being returned which may cause side effects. See bug for details. Closes-Bug: #1530179 Change-Id: I8368255f00ab3e9586c8ff28dfe6739541000810 --- neutron/db/dvr_mac_db.py | 9 +++--- neutron/tests/unit/db/test_dvr_mac_db.py | 41 ++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/neutron/db/dvr_mac_db.py b/neutron/db/dvr_mac_db.py index 53f6dd9e70e..952125d38a7 100644 --- a/neutron/db/dvr_mac_db.py +++ b/neutron/db/dvr_mac_db.py @@ -169,11 +169,12 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase): else: # retrieve the gateway port on this subnet if fixed_ips: - filter = fixed_ips[0] + ip_address = fixed_ips[0]['ip_address'] else: - filter = {'fixed_ips': {'subnet_id': [subnet], - 'ip_address': - [subnet_info['gateway_ip']]}} + ip_address = subnet_info['gateway_ip'] + + filter = {'fixed_ips': {'subnet_id': [subnet], + 'ip_address': [ip_address]}} internal_gateway_ports = self.plugin.get_ports( context, filters=filter) diff --git a/neutron/tests/unit/db/test_dvr_mac_db.py b/neutron/tests/unit/db/test_dvr_mac_db.py index f6d4172d5da..c827aeea920 100644 --- a/neutron/tests/unit/db/test_dvr_mac_db.py +++ b/neutron/tests/unit/db/test_dvr_mac_db.py @@ -19,7 +19,7 @@ from oslo_config import cfg from neutron import context from neutron.db import dvr_mac_db from neutron.extensions import dvr -from neutron.tests.unit import testlib_api +from neutron.tests.unit.plugins.ml2 import test_plugin class DVRDbMixinImpl(dvr_mac_db.DVRDbMixin): @@ -28,7 +28,7 @@ class DVRDbMixinImpl(dvr_mac_db.DVRDbMixin): self.notifier = notifier -class DvrDbMixinTestCase(testlib_api.SqlTestCase): +class DvrDbMixinTestCase(test_plugin.Ml2PluginV2TestCase): def setUp(self): super(DvrDbMixinTestCase, self).setUp() @@ -90,3 +90,40 @@ class DvrDbMixinTestCase(testlib_api.SqlTestCase): with mock.patch.object(self.mixin, '_create_dvr_mac_address') as f: self.mixin.get_dvr_mac_address_by_host(self.ctx, 'foo_host') self.assertEqual(1, f.call_count) + + def test_get_subnet_for_dvr_returns_correct_mac(self): + with self.subnet() as subnet,\ + self.port(subnet=subnet),\ + self.port(subnet=subnet): + dvr_subnet = self.mixin.get_subnet_for_dvr(self.ctx, + subnet['subnet']['id']) + # no gateway port should be found so no info should be returned + self.assertEqual({}, dvr_subnet) + with self.port( + subnet=subnet, + fixed_ips=[{'ip_address': subnet['subnet'][ + 'gateway_ip']}]) as gw_port: + dvr_subnet = self.mixin.get_subnet_for_dvr( + self.ctx, subnet['subnet']['id']) + self.assertEqual(gw_port['port']['mac_address'], + dvr_subnet['gateway_mac']) + + def test_get_subnet_for_dvr_returns_correct_mac_fixed_ips_passed(self): + with self.subnet() as subnet,\ + self.port(subnet=subnet, + fixed_ips=[{'ip_address': '10.0.0.2'}]),\ + self.port(subnet=subnet, + fixed_ips=[{'ip_address': '10.0.0.3'}]): + fixed_ips = [{'subnet_id': subnet['subnet']['id'], + 'ip_address': '10.0.0.4'}] + dvr_subnet = self.mixin.get_subnet_for_dvr( + self.ctx, subnet['subnet']['id'], fixed_ips) + # no gateway port should be found so no info should be returned + self.assertEqual({}, dvr_subnet) + with self.port( + subnet=subnet, + fixed_ips=[{'ip_address': '10.0.0.4'}]) as gw_port: + dvr_subnet = self.mixin.get_subnet_for_dvr( + self.ctx, subnet['subnet']['id'], fixed_ips) + self.assertEqual(gw_port['port']['mac_address'], + dvr_subnet['gateway_mac'])