self._populate_subnets_for_ports(context, port_list)
return port_list
+ def _generate_arp_table_and_notify_agent(
+ self, context, fixed_ip, mac_address, notifier):
+ """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]}}
+ ports = self._core_plugin.get_ports(context, filters=filters)
+ for port in ports:
+ if port['device_owner'] == l3_const.DEVICE_OWNER_DVR_INTERFACE:
+ router_id = port['device_id']
+ router_dict = self._get_router(context, router_id)
+ if router_dict.extra_attributes.distributed:
+ arp_table = {'ip_address': ip_address,
+ 'mac_address': mac_address,
+ 'subnet_id': subnet}
+ notifier(context, router_id, arp_table)
+ return
+
def update_arp_entry_for_dvr_service_port(
self, context, port_dict, action):
"""Notify L3 agents of ARP table entry for dvr service port.
if not (n_utils.is_dvr_serviced(port_dict['device_owner']) and
port_dict['fixed_ips']):
return
- ip_address = port_dict['fixed_ips'][0]['ip_address']
- subnet = port_dict['fixed_ips'][0]['subnet_id']
- filters = {'fixed_ips': {'subnet_id': [subnet]}}
- ports = self._core_plugin.get_ports(context, filters=filters)
- for port in ports:
- if port['device_owner'] == l3_const.DEVICE_OWNER_DVR_INTERFACE:
- router_id = port['device_id']
- router_dict = self._get_router(context, router_id)
- if router_dict.extra_attributes.distributed:
- arp_table = {'ip_address': ip_address,
- 'mac_address': port_dict['mac_address'],
- 'subnet_id': subnet}
- if action == "add":
- notify_action = self.l3_rpc_notifier.add_arp_entry
- elif action == "del":
- notify_action = self.l3_rpc_notifier.del_arp_entry
- notify_action(context, router_id, arp_table)
- return
+ changed_fixed_ips = port_dict['fixed_ips']
+ for fixed_ip in changed_fixed_ips:
+ if action == "add":
+ notifier = self.l3_rpc_notifier.add_arp_entry
+ elif action == "del":
+ notifier = self.l3_rpc_notifier.del_arp_entry
+ else:
+ return
+
+ self._generate_arp_table_and_notify_agent(
+ context, fixed_ip, port_dict['mac_address'], notifier)
def delete_csnat_router_interface_ports(self, context,
router, subnet_id=None):
event, resource, trigger, **removed_router_args)
if not n_utils.is_dvr_serviced(new_device_owner):
return
+ is_fixed_ips_changed = (
+ 'fixed_ips' in new_port and
+ 'fixed_ips' in original_port and
+ new_port['fixed_ips'] != original_port['fixed_ips'])
is_new_port_binding_changed = (
new_port[portbindings.HOST_ID] and
(original_port[portbindings.HOST_ID] !=
l3plugin.dvr_handle_new_service_port(context, new_port)
l3plugin.update_arp_entry_for_dvr_service_port(
context, new_port, "add")
- elif kwargs.get('mac_address_updated'):
+ elif kwargs.get('mac_address_updated') or is_fixed_ips_changed:
l3plugin.update_arp_entry_for_dvr_service_port(
context, new_port, "add")
gp.return_value = plugin
port = {
'id': 'my_port_id',
- 'fixed_ips': [{
- 'ip_address': 'my_ip',
- 'subnet_id': 'my_subnet_id',
- }],
+ 'fixed_ips': [
+ {'subnet_id': '51edc9e0-24f9-47f2-8e1e-2a41cb691323',
+ 'ip_address': '10.0.0.11'},
+ {'subnet_id': '2b7c8a07-6f8e-4937-8701-f1d5da1a807c',
+ 'ip_address': '10.0.0.21'},
+ {'subnet_id': '48534187-f077-4e81-93ff-81ec4cc0ad3b',
+ 'ip_address': 'fd45:1515:7e0:0:f816:3eff:fe1a:1111'}],
'mac_address': 'my_mac',
'device_owner': device_owner
}
self.mixin.update_arp_entry_for_dvr_service_port(
self.ctx, port, action)
if action == 'add':
- self.assertTrue(l3_notify.add_arp_entry.called)
+ self.assertEqual(3, l3_notify.add_arp_entry.call_count)
elif action == 'del':
- self.assertTrue(l3_notify.del_arp_entry.called)
+ self.assertTrue(3, l3_notify.del_arp_entry.call_count)
def test_update_arp_entry_for_dvr_service_port_added(self):
action = 'add'