]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
l2-pop shouldn't notify agent about inactive ports
authorChengli XU <xuchengli@corp.netease.com>
Wed, 25 Jun 2014 14:26:04 +0000 (22:26 +0800)
committerRomil Gupta <romilg@hp.com>
Fri, 6 Feb 2015 16:47:55 +0000 (08:47 -0800)
When an agent starts, or the first port of an agent becomes active,
l2 population mechanism driver will notify the agent of all ports on other agents.
It should not notify about inactive ports.

Basically, this patch-set is needed for fixing the bug 1332450.

Co-Authored-By: Romil Gupta <romilg@hp.com>
Closes-Bug: #1334292
Change-Id: Ifbbd7c4e22d4a6383a3c77a9d9ac9a37302c38c3

neutron/plugins/ml2/drivers/l2pop/db.py
neutron/plugins/ml2/drivers/l2pop/mech_driver.py
neutron/tests/unit/ml2/drivers/test_l2population.py

index 65faa7ce04c1d3640deabb5eb7c359bcd4a8955c..3cdfb1dd9272209da7247fd176fb23466298120c 100644 (file)
@@ -15,7 +15,6 @@
 
 from oslo_serialization import jsonutils
 from oslo_utils import timeutils
-from sqlalchemy import sql
 
 from neutron.common import constants as const
 from neutron.db import agents_db
@@ -56,7 +55,7 @@ class L2populationDbMixin(base_db.CommonDbMixin):
                                      l2_const.SUPPORTED_AGENT_TYPES))
             return query.first()
 
-    def get_network_ports(self, session, network_id):
+    def _get_active_network_ports(self, session, network_id):
         with session.begin(subtransactions=True):
             query = session.query(ml2_models.PortBinding,
                                   agents_db.Agent)
@@ -65,17 +64,18 @@ class L2populationDbMixin(base_db.CommonDbMixin):
                                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 == sql.true(),
+                                 models_v2.Port.status ==
+                                 const.PORT_STATUS_ACTIVE,
                                  agents_db.Agent.agent_type.in_(
                                      l2_const.SUPPORTED_AGENT_TYPES))
             return query
 
-    def get_nondvr_network_ports(self, session, network_id):
-        query = self.get_network_ports(session, network_id)
+    def get_nondvr_active_network_ports(self, session, network_id):
+        query = self._get_active_network_ports(session, network_id)
         return query.filter(models_v2.Port.device_owner !=
                             const.DEVICE_OWNER_DVR_INTERFACE)
 
-    def get_dvr_network_ports(self, session, network_id):
+    def get_dvr_active_network_ports(self, session, network_id):
         with session.begin(subtransactions=True):
             query = session.query(ml2_models.DVRPortBinding,
                                   agents_db.Agent)
@@ -84,7 +84,8 @@ class L2populationDbMixin(base_db.CommonDbMixin):
                                ml2_models.DVRPortBinding.host)
             query = query.join(models_v2.Port)
             query = query.filter(models_v2.Port.network_id == network_id,
-                                 models_v2.Port.admin_state_up == sql.true(),
+                                 models_v2.Port.status ==
+                                 const.PORT_STATUS_ACTIVE,
                                  models_v2.Port.device_owner ==
                                  const.DEVICE_OWNER_DVR_INTERFACE,
                                  agents_db.Agent.agent_type.in_(
index a93c0c76aed4aa0afc95197b8d1c33950eab8a91..fc413fe95a4214a79383ab84312a80766cfc19ac 100644 (file)
@@ -185,9 +185,9 @@ class L2populationMechanismDriver(api.MechanismDriver,
                               'network_type': segment['network_type'],
                               'ports': {}}}
         tunnel_network_ports = (
-            self.get_dvr_network_ports(session, network_id).all())
+            self.get_dvr_active_network_ports(session, network_id).all())
         fdb_network_ports = (
-            self.get_nondvr_network_ports(session, network_id).all())
+            self.get_nondvr_active_network_ports(session, network_id).all())
         ports = agent_fdb_entries[network_id]['ports']
         ports.update(self._get_tunnels(
             fdb_network_ports + tunnel_network_ports,
index 0c51de404c99cfc0c00495f1f8050833f6fd2e3b..12f0f6b21aa7977da10b6a2a2c70dc4d3cc13cdb 100644 (file)
@@ -303,6 +303,46 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
                     self.mock_fanout.assert_called_with(
                         mock.ANY, 'add_fdb_entries', expected)
 
+    def test_fdb_called_for_active_ports(self):
+        self._register_ml2_agents()
+
+        with self.subnet(network=self._network) as subnet:
+            host_arg = {portbindings.HOST_ID: HOST}
+            with self.port(subnet=subnet,
+                           device_owner=DEVICE_OWNER_COMPUTE,
+                           arg_list=(portbindings.HOST_ID,),
+                           **host_arg) as port1:
+                host_arg = {portbindings.HOST_ID: HOST + '_2'}
+                with self.port(subnet=subnet,
+                               device_owner=DEVICE_OWNER_COMPUTE,
+                               arg_list=(portbindings.HOST_ID,),
+                               **host_arg):
+                    p1 = port1['port']
+
+                    device1 = 'tap' + p1['id']
+
+                    self.mock_cast.reset_mock()
+                    self.mock_fanout.reset_mock()
+                    self.callbacks.update_device_up(self.adminContext,
+                                                    agent_id=HOST,
+                                                    device=device1)
+
+                    p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
+
+                    self.assertFalse(self.mock_cast.called)
+
+                    expected2 = {p1['network_id']:
+                                 {'ports':
+                                  {'20.0.0.1': [constants.FLOODING_ENTRY,
+                                                l2pop_rpc.PortInfo(
+                                                    p1['mac_address'],
+                                                    p1_ips[0])]},
+                                  'network_type': 'vxlan',
+                                  'segment_id': 1}}
+
+                    self.mock_fanout.assert_called_with(
+                        mock.ANY, 'add_fdb_entries', expected2)
+
     def test_fdb_add_two_agents(self):
         self._register_ml2_agents()
 
@@ -323,13 +363,17 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
                     p1 = port1['port']
                     p2 = port2['port']
 
-                    device = 'tap' + p1['id']
+                    device1 = 'tap' + p1['id']
+                    device2 = 'tap' + p2['id']
 
                     self.mock_cast.reset_mock()
                     self.mock_fanout.reset_mock()
+                    self.callbacks.update_device_up(self.adminContext,
+                                                    agent_id=HOST + '_2',
+                                                    device=device2)
                     self.callbacks.update_device_up(self.adminContext,
                                                     agent_id=HOST,
-                                                    device=device)
+                                                    device=device1)
 
                     p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
                     p2_ips = [p['ip_address'] for p in p2['fixed_ips']]
@@ -381,13 +425,17 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
                             p1 = port1['port']
                             p3 = port3['port']
 
-                            device = 'tap' + p3['id']
+                            device1 = 'tap' + p1['id']
+                            device3 = 'tap' + p3['id']
 
                             self.mock_cast.reset_mock()
                             self.mock_fanout.reset_mock()
+                            self.callbacks.update_device_up(
+                                self.adminContext, agent_id=HOST + '_2',
+                                device=device1)
                             self.callbacks.update_device_up(
                                 self.adminContext, agent_id=HOST,
-                                device=device)
+                                device=device3)
 
                             p1_ips = [p['ip_address']
                                       for p in p1['fixed_ips']]
@@ -886,10 +934,10 @@ class TestL2PopulationMechDriver(base.BaseTestCase):
                                   'get_agent_ip',
                                   side_effect=agent_ip_side_effect),
                 mock.patch.object(l2pop_db.L2populationDbMixin,
-                                  'get_nondvr_network_ports',
+                                  'get_nondvr_active_network_ports',
                                   new=fdb_network_ports_query),
                 mock.patch.object(l2pop_db.L2populationDbMixin,
-                                  'get_dvr_network_ports',
+                                  'get_dvr_active_network_ports',
                                   new=tunnel_network_ports_query)):
             session = mock.Mock()
             agent = mock.Mock()