From de24799696a8199b13223c2ca3820a9ef015bbe0 Mon Sep 17 00:00:00 2001 From: Sylvain Afchain Date: Wed, 16 Oct 2013 23:28:44 +0200 Subject: [PATCH] Fix L2pop to not send updates for unrelated networks With this patch L2 population mechanism driver sends updates only with ports related to the network id of the port which is being updated. Fixes bug: 1240744 Change-Id: If7d51ce26bf0d0837a00da07fe85f48d55e681c6 --- neutron/plugins/ml2/drivers/l2pop/db.py | 1 + .../unit/ml2/drivers/test_l2population.py | 84 +++++++++++++------ 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/neutron/plugins/ml2/drivers/l2pop/db.py b/neutron/plugins/ml2/drivers/l2pop/db.py index b176a396b..e7bf92d3b 100644 --- a/neutron/plugins/ml2/drivers/l2pop/db.py +++ b/neutron/plugins/ml2/drivers/l2pop/db.py @@ -60,6 +60,7 @@ class L2populationDbMixin(base_db.CommonDbMixin): query = query.join(agents_db.Agent, agents_db.Agent.host == ml2_models.PortBinding.host) + query = query.join(models_v2.Port) query = query.filter(models_v2.Port.network_id == network_id, models_v2.Port.admin_state_up == True, agents_db.Agent.agent_type.in_( diff --git a/neutron/tests/unit/ml2/drivers/test_l2population.py b/neutron/tests/unit/ml2/drivers/test_l2population.py index 57a0a2bbe..f32402d65 100644 --- a/neutron/tests/unit/ml2/drivers/test_l2population.py +++ b/neutron/tests/unit/ml2/drivers/test_l2population.py @@ -265,39 +265,71 @@ class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase): self._register_ml2_agents() with self.subnet(network=self._network) as subnet: - host_arg = {portbindings.HOST_ID: HOST} + host_arg = {portbindings.HOST_ID: HOST + '_2'} with self.port(subnet=subnet, arg_list=(portbindings.HOST_ID,), **host_arg) as port1: with self.subnet(cidr='10.1.0.0/24') as subnet2: - host_arg = {portbindings.HOST_ID: HOST + '_2'} with self.port(subnet=subnet2, arg_list=(portbindings.HOST_ID,), **host_arg): - p1 = port1['port'] - - device = 'tap' + p1['id'] - - self.mock_fanout.reset_mock() - self.callbacks.update_device_up(self.adminContext, - agent_id=HOST, - device=device) - - p1_ips = [p['ip_address'] for p in p1['fixed_ips']] - expected = {'args': - {'fdb_entries': - {p1['network_id']: - {'ports': - {'20.0.0.1': [constants.FLOODING_ENTRY, - [p1['mac_address'], - p1_ips[0]]]}, - 'network_type': 'vxlan', - 'segment_id': 1}}}, - 'namespace': None, - 'method': 'add_fdb_entries'} - - self.mock_fanout.assert_called_with( - mock.ANY, expected, topic=self.fanout_topic) + host_arg = {portbindings.HOST_ID: HOST} + with self.port(subnet=subnet, + arg_list=(portbindings.HOST_ID,), + **host_arg) as port3: + p1 = port1['port'] + p3 = port3['port'] + + device = 'tap' + p3['id'] + + self.mock_cast.reset_mock() + self.mock_fanout.reset_mock() + self.callbacks.update_device_up( + self.adminContext, agent_id=HOST, + device=device) + + p1_ips = [p['ip_address'] + for p in p1['fixed_ips']] + expected1 = {'args': + {'fdb_entries': + {p1['network_id']: + {'ports': + {'20.0.0.2': + [constants.FLOODING_ENTRY, + [p1['mac_address'], + p1_ips[0]]]}, + 'network_type': 'vxlan', + 'segment_id': 1}}}, + 'namespace': None, + 'method': 'add_fdb_entries'} + + topic = topics.get_topic_name(topics.AGENT, + topics.L2POPULATION, + topics.UPDATE, + HOST) + + self.mock_cast.assert_called_with(mock.ANY, + expected1, + topic=topic) + + p3_ips = [p['ip_address'] + for p in p3['fixed_ips']] + expected2 = {'args': + {'fdb_entries': + {p1['network_id']: + {'ports': + {'20.0.0.1': + [constants.FLOODING_ENTRY, + [p3['mac_address'], + p3_ips[0]]]}, + 'network_type': 'vxlan', + 'segment_id': 1}}}, + 'namespace': None, + 'method': 'add_fdb_entries'} + + self.mock_fanout.assert_called_with( + mock.ANY, expected2, + topic=self.fanout_topic) def test_fdb_remove_called_from_rpc(self): self._register_ml2_agents() -- 2.45.2