]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Broadcast service port's arp in DVR
authorleejian0612 <ljianbj@cn.ibm.com>
Wed, 5 Aug 2015 08:00:35 +0000 (16:00 +0800)
committerleejian0612 <ljianbj@cn.ibm.com>
Thu, 6 Aug 2015 10:23:21 +0000 (18:23 +0800)
When creating VMs, DVR router will broadcast VM's arp details to all the
l3 agents hosting it. that enable dvr can forwarding networking traffic
in link layer, but when the port is attached to the service liking
lbaas, their arp will not be broadcast, so the dvr do not know its mac,
and will cause that vms in other subnet can not reach the service port
through the dvr router.

Change-Id: Ia78a35f39981d6659fc220e02fb10917bda74e04
Closes-Bug: #1481613

neutron/db/l3_dvr_db.py
neutron/tests/unit/db/test_l3_dvr_db.py

index ff20cbb224c780dc8d699ee5de63713e70988676..f332a6db7dc429c0469c2691cd788dfcd0c6b66b 100644 (file)
@@ -661,9 +661,9 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
         router.
         """
 
-        # Check this is a valid VM port
-        if ("compute:" not in port_dict['device_owner'] or
-            not port_dict['fixed_ips']):
+        # Check this is a valid VM or 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']
index 419e168fb7a29d8d361146d021c3b1d5e20affe7..b10ee8d9c3ddcd6191016b670d9267393f744545 100644 (file)
@@ -551,3 +551,44 @@ class L3DvrTestCase(testlib_api.SqlTestCase):
             kwargs = {'context': self.ctx, 'router': router_db}
             mock_notify.assert_called_once_with(
                 'router', 'before_update', self.mixin, **kwargs)
+
+    def _test_dvr_vmarp_table_update(self, device_owner, action):
+        with mock.patch.object(manager.NeutronManager, 'get_plugin') as gp,\
+                mock.patch.object(self.mixin, '_get_router') as grtr:
+            plugin = mock.Mock()
+            dvr_router = mock.Mock()
+            l3_notify = self.mixin.l3_rpc_notifier = mock.Mock()
+            gp.return_value = plugin
+            port = {
+                'id': 'my_port_id',
+                'fixed_ips': [{
+                    'ip_address': 'my_ip',
+                    'subnet_id': 'my_subnet_id',
+                }],
+                'mac_address': 'my_mac',
+                'device_owner': device_owner
+            }
+            dvr_port = {
+                'id': 'dvr_port_id',
+                'fixed_ips': mock.ANY,
+                'device_owner': l3_const.DEVICE_OWNER_DVR_INTERFACE,
+                'device_id': 'dvr_router_id'
+            }
+            plugin.get_ports.return_value = [port, dvr_port]
+            grtr.return_value = dvr_router
+            dvr_router.extra_attributes.distributed = True
+            self.mixin.dvr_vmarp_table_update(self.ctx, port, action)
+            if action == 'add':
+                self.assertTrue(l3_notify.add_arp_entry.called)
+            elif action == 'del':
+                self.assertTrue(l3_notify.del_arp_entry.called)
+
+    def test_dvr_vmarp_table_update_with_service_port_added(self):
+        action = 'add'
+        device_owner = l3_const.DEVICE_OWNER_LOADBALANCER
+        self._test_dvr_vmarp_table_update(device_owner, action)
+
+    def test_dvr_vmarp_table_update_with_service_port_deleted(self):
+        action = 'del'
+        device_owner = l3_const.DEVICE_OWNER_LOADBALANCER
+        self._test_dvr_vmarp_table_update(device_owner, action)