DVR: Fix binding info for DVR port not found error
Recently we have been seeing an error in neutron associated with DVR routers, that says 'Binding info for DVR port not found'. This error is thrown when the 'get_bound_port_context' is called when trying to notify_l2pop_port_wiring. notify_l2pop_port_wiring is intended for router 'HA' ports, so the get_bound_port_context should be called here only for 'HA' ports. This was introduced by a recent refactor in neutron Icd4cd4e3f735e88299e86468380c5f786e7628fe Change-Id: I1c636344068518aa26be6c96c598c61b7f0f3563 Closes-Bug: #1702769
This commit is contained in:
parent
1a11bc9605
commit
9e9a8a07c3
|
@ -302,6 +302,13 @@ class RpcCallbacks(type_tunnel.TunnelRpcCallbackMixin):
|
|||
'l2population')
|
||||
if not l2pop_driver:
|
||||
return
|
||||
port = ml2_db.get_port(rpc_context, port_id)
|
||||
if not port:
|
||||
return
|
||||
# NOTE: DVR ports are already handled and updated through l2pop
|
||||
# and so we don't need to update it again here
|
||||
if port['device_owner'] == n_const.DEVICE_OWNER_DVR_INTERFACE:
|
||||
return
|
||||
port_context = plugin.get_bound_port_context(
|
||||
rpc_context, port_id)
|
||||
if not port_context:
|
||||
|
|
|
@ -239,12 +239,19 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
|
|||
plugin.update_port(self.adminContext, port['id'],
|
||||
{port_def.RESOURCE_NAME: port})
|
||||
|
||||
def _get_first_interface(self, net_id, router_id):
|
||||
def _get_first_interface(self, net_id, router):
|
||||
plugin = directory.get_plugin()
|
||||
device_filter = {'device_id': [router_id],
|
||||
'device_owner':
|
||||
[constants.DEVICE_OWNER_HA_REPLICATED_INT]}
|
||||
return plugin.get_ports(self.adminContext, filters=device_filter)[0]
|
||||
if router['distributed']:
|
||||
device_filter = {'device_id': [router['id']],
|
||||
'device_owner':
|
||||
[constants.DEVICE_OWNER_DVR_INTERFACE]}
|
||||
else:
|
||||
device_filter = {'device_id': [router['id']],
|
||||
'device_owner':
|
||||
[constants.DEVICE_OWNER_HA_REPLICATED_INT]}
|
||||
ports = plugin.get_ports(self.adminContext, filters=device_filter)
|
||||
if ports:
|
||||
return ports[0]
|
||||
|
||||
def _add_router_interface(self, subnet, router, host):
|
||||
interface_info = {'subnet_id': subnet['id']}
|
||||
|
@ -254,7 +261,7 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
|
|||
self.adminContext,
|
||||
{router['id']: n_const.HA_ROUTER_STATE_ACTIVE}, host)
|
||||
|
||||
port = self._get_first_interface(subnet['network_id'], router['id'])
|
||||
port = self._get_first_interface(subnet['network_id'], router)
|
||||
|
||||
self.mock_cast.reset_mock()
|
||||
self.mock_fanout.reset_mock()
|
||||
|
@ -268,6 +275,12 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
|
|||
self._bind_router(router['id'], router['tenant_id'])
|
||||
return router
|
||||
|
||||
def _create_dvr_router(self):
|
||||
self._setup_l3()
|
||||
router = self._create_router(distributed=True)
|
||||
self._bind_router(router['id'], router['tenant_id'])
|
||||
return router
|
||||
|
||||
def _verify_remove_fdb(self, expected, agent_id, device, host=None):
|
||||
self.mock_fanout.reset_mock()
|
||||
self.callbacks.update_device_down(self.adminContext, agent_id=host,
|
||||
|
@ -339,6 +352,36 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
|
|||
self.mock_fanout.assert_called_with(
|
||||
mock.ANY, 'remove_fdb_entries', expected)
|
||||
|
||||
def test_ha_agents_with_dvr_rtr_does_not_get_other_fdb(self):
|
||||
router = self._create_dvr_router()
|
||||
directory.add_plugin(plugin_constants.L3, self.plugin)
|
||||
with self.subnet(network=self._network, enable_dhcp=False) as snet:
|
||||
host_arg = {portbindings.HOST_ID: HOST_4, 'admin_state_up': True}
|
||||
with self.port(subnet=snet,
|
||||
device_owner=DEVICE_OWNER_COMPUTE,
|
||||
arg_list=(portbindings.HOST_ID,),
|
||||
**host_arg) as port1:
|
||||
p1 = port1['port']
|
||||
device1 = 'tap' + p1['id']
|
||||
self.callbacks.update_device_up(
|
||||
self.adminContext, agent_id=HOST_4, device=device1)
|
||||
|
||||
subnet = snet['subnet']
|
||||
port = self._add_router_interface(subnet, router, HOST)
|
||||
|
||||
self.mock_cast.assert_not_called()
|
||||
self.mock_fanout.assert_not_called()
|
||||
|
||||
self.mock_cast.reset_mock()
|
||||
self.mock_fanout.reset_mock()
|
||||
|
||||
self.callbacks.update_device_up(
|
||||
self.adminContext, agent_id=HOST_2,
|
||||
device=port['id'], host=HOST_2)
|
||||
|
||||
self.mock_cast.assert_not_called()
|
||||
self.mock_fanout.assert_not_called()
|
||||
|
||||
def test_ha_agents_get_other_fdb(self):
|
||||
# First network port is added on HOST4, then HA router port is
|
||||
# added on HOST and HOST2.
|
||||
|
|
Loading…
Reference in New Issue