Change the way to distinguish the port type

In delete_port_postcommit, a DVR port (port['device_owner'] =
DEVICE_OWNER_ROUTER_SNAT) can match on l2pop_db.HA_ROUTER_PORTS[1],
but can not get any fdb entries by _get_ha_port_agents_fdb. Then,
the fdb_entries[network_id]['ports'] is been overwritten by {}. So
the associated flow entries will not be deleted.

Closes-Bug: #1668277
Change-Id: I7b621157fe85945acd99e4f08b6370d2f9c3d44d
This commit is contained in:
Yaohua Yan 2017-02-27 22:26:08 +08:00
parent b8f3abeea3
commit 3593620faa
2 changed files with 41 additions and 1 deletions

View File

@ -73,7 +73,8 @@ class L2populationMechanismDriver(api.MechanismDriver):
agent_host = context.host
fdb_entries = self._get_agent_fdb(
context, context.bottom_bound_segment, port, agent_host)
if port['device_owner'] in l2pop_db.HA_ROUTER_PORTS and fdb_entries:
if fdb_entries and l3_hamode_db.is_ha_router_port(
context, port['device_owner'], port['device_id']):
session = db_api.get_reader_session()
network_id = port['network_id']
other_fdb_ports = self._get_ha_port_agents_fdb(

View File

@ -30,6 +30,7 @@ from neutron.db import l3_agentschedulers_db
from neutron.db import l3_hamode_db
from neutron.extensions import portbindings
from neutron.extensions import providernet as pnet
from neutron.plugins.ml2 import db as ml2_db
from neutron.plugins.ml2 import driver_context
from neutron.plugins.ml2.drivers.l2pop import db as l2pop_db
from neutron.plugins.ml2.drivers.l2pop import mech_driver as l2pop_mech_driver
@ -1111,6 +1112,44 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
# are raised.
l2pop_mech.delete_port_postcommit(port_context)
def test_delete_dvr_snat_port_fdb_entries(self):
l2pop_mech = l2pop_mech_driver.L2populationMechanismDriver()
l2pop_mech.initialize()
self._setup_l3()
with self.subnet(network=self._network, enable_dhcp=False) as snet:
host_arg = {portbindings.HOST_ID: HOST, 'admin_state_up': True}
with self.port(subnet=snet,
device_owner=constants.DEVICE_OWNER_ROUTER_SNAT,
arg_list=(portbindings.HOST_ID,),
**host_arg) as p:
device = 'tap' + p['port']['id']
self.callbacks.update_device_up(self.adminContext,
agent_id=HOST, device=device)
dvr_snat_port = ml2_db.get_port(self.adminContext,
p['port']['id'])
self.mock_fanout.reset_mock()
context = mock.Mock()
context.current = dvr_snat_port
context.host = HOST
segment = {'network_type': 'vxlan', 'segmentation_id': 1}
context.bottom_bound_segment = segment
expected = {self._network['network']['id']:
{'segment_id': segment['segmentation_id'],
'network_type': segment['network_type'],
'ports': {'20.0.0.1':
[l2pop_rpc.PortInfo(
mac_address=p['port']['mac_address'],
ip_address=p['port']['fixed_ips'][0]
['ip_address'])]}}}
l2pop_mech.delete_port_postcommit(context)
self.mock_fanout.assert_called_with(
mock.ANY, 'remove_fdb_entries', expected)
def test_fixed_ips_change_unbound_port_no_rpc(self):
l2pop_mech = l2pop_mech_driver.L2populationMechanismDriver()
l2pop_mech.initialize()