Fix notification about arp entries for dvr routers

In method _generate_arp_table_and_notify_agent in neutron.db.l3_dvr_db
module notifiations about arp table was send only to one router
connected to subnet.
Now it will check if subnet is connected to more than one
dvr router and will send same notification to all such routers.

Closes-Bug: #1815913

Change-Id: I6a7d7f6645a8a7b5219788d51e17d54844d145bc
(cherry picked from commit 1f104a093c)
This commit is contained in:
Slawek Kaplonski 2019-02-14 14:35:25 +01:00
parent a235901c92
commit 8554a72b6f
2 changed files with 26 additions and 7 deletions

View File

@ -1027,16 +1027,15 @@ class _DVRAgentInterfaceMixin(object):
"""Generates the arp table entry and notifies the l3 agent."""
ip_address = fixed_ip['ip_address']
subnet = fixed_ip['subnet_id']
filters = {'fixed_ips': {'subnet_id': [subnet]},
'device_owner': [const.DEVICE_OWNER_DVR_INTERFACE]}
ports = self._core_plugin.get_ports(context, filters=filters)
router_id = next((port['device_id'] for port in ports), None)
if not router_id:
return
arp_table = {'ip_address': ip_address,
'mac_address': mac_address,
'subnet_id': subnet}
notifier(context, router_id, arp_table)
filters = {'fixed_ips': {'subnet_id': [subnet]},
'device_owner': [const.DEVICE_OWNER_DVR_INTERFACE]}
ports = self._core_plugin.get_ports(context, filters=filters)
routers = [port['device_id'] for port in ports]
for router_id in routers:
notifier(context, router_id, arp_table)
def _get_subnet_id_for_given_fixed_ip(
self, context, fixed_ip, port_dict):

View File

@ -858,6 +858,26 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
port=mock.ANY,
interface_info=interface_info)
def test__generate_arp_table_and_notify_agent(self):
fixed_ip = {
'ip_address': '1.2.3.4',
'subnet_id': _uuid()}
mac_address = "00:11:22:33:44:55"
expected_arp_table = {
'ip_address': fixed_ip['ip_address'],
'subnet_id': fixed_ip['subnet_id'],
'mac_address': mac_address}
notifier = mock.Mock()
ports = [{'id': _uuid(), 'device_id': 'router_1'},
{'id': _uuid(), 'device_id': 'router_2'}]
with mock.patch.object(self.core_plugin, "get_ports",
return_value=ports):
self.mixin._generate_arp_table_and_notify_agent(
self.ctx, fixed_ip, mac_address, notifier)
notifier.assert_has_calls([
mock.call(self.ctx, "router_1", expected_arp_table),
mock.call(self.ctx, "router_2", expected_arp_table)])
def _test_update_arp_entry_for_dvr_service_port(
self, device_owner, action):
router_dict = {'name': 'test_router', 'admin_state_up': True,