]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix gateway port could not retrieve for subnet
authorSwaminathan Vasudevan <swaminathan.vasudevan@hp.com>
Wed, 29 Apr 2015 05:50:31 +0000 (22:50 -0700)
committerSwaminathan Vasudevan <swaminathan.vasudevan@hp.com>
Mon, 20 Jul 2015 18:46:34 +0000 (18:46 +0000)
In DVR routers when a port is added to a router, then
the command succeeds but the l2 ovs agent raises an
error stating that it could not retrieve the gateway
port for the subnet.

The reason for this is there is mismatch in the
ip_address returned from the subnet for the gateway
port and the actual ip_address of the port that we
added to the router.

Since the subnet info was passed to "get_subnet_for_dvr"
this mismatch was seen.

Instead of passing the subnet we will be passing the
actual fixed_ips with all the details and the subnet
gateway port will be filtered based on the ip_address
in the fixed_ips passed.

Closes-Bug: #1404823

Change-Id: I87a3983951f814350e79f5e2274f4639bb6bc0f5

neutron/api/rpc/handlers/dvr_rpc.py
neutron/db/dvr_mac_db.py
neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py
neutron/tests/unit/api/rpc/handlers/test_dvr_rpc.py

index 8b6574707e8d9ac8a97181e289e7ce0bef2200e2..02909b6f70a3fc38a2235b8023efd31f7852c50b 100644 (file)
@@ -32,6 +32,9 @@ class DVRServerRpcApi(object):
     can be found below: DVRServerRpcCallback.  For more information on changing
     rpc interfaces, see doc/source/devref/rpc_api.rst.
     """
+    # 1.0 Initial Version
+    # 1.1 Support for passing 'fixed_ips' in get_subnet_for_dvr function.
+    #     Passing 'subnet" will be deprecated in the next release.
 
     def __init__(self, topic):
         target = oslo_messaging.Target(topic=topic, version='1.0',
@@ -55,9 +58,10 @@ class DVRServerRpcApi(object):
                           host=host, subnet=subnet)
 
     @log_helpers.log_method_call
-    def get_subnet_for_dvr(self, context, subnet):
+    def get_subnet_for_dvr(self, context, subnet, fixed_ips):
         cctxt = self.client.prepare()
-        return cctxt.call(context, 'get_subnet_for_dvr', subnet=subnet)
+        return cctxt.call(
+            context, 'get_subnet_for_dvr', subnet=subnet, fixed_ips=fixed_ips)
 
 
 class DVRServerRpcCallback(object):
@@ -70,8 +74,10 @@ class DVRServerRpcCallback(object):
 
     # History
     #   1.0 Initial version
+    #   1.1 Support for passing the 'fixed_ips" in get_subnet_for_dvr.
+    #       Passing subnet will be deprecated in the next release.
 
-    target = oslo_messaging.Target(version='1.0',
+    target = oslo_messaging.Target(version='1.1',
                                    namespace=constants.RPC_NAMESPACE_DVR)
 
     @property
@@ -96,8 +102,10 @@ class DVRServerRpcCallback(object):
             host, subnet)
 
     def get_subnet_for_dvr(self, context, **kwargs):
+        fixed_ips = kwargs.get('fixed_ips')
         subnet = kwargs.get('subnet')
-        return self.plugin.get_subnet_for_dvr(context, subnet)
+        return self.plugin.get_subnet_for_dvr(
+            context, subnet, fixed_ips=fixed_ips)
 
 
 class DVRAgentRpcApiMixin(object):
index c0f0d656aa748e17ca3471c9196cb40972b50dd9..8ec13042b850138537bd84d93d55611076369140 100644 (file)
@@ -155,15 +155,25 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
         return ports_by_host
 
     @log_helpers.log_method_call
-    def get_subnet_for_dvr(self, context, subnet):
+    def get_subnet_for_dvr(self, context, subnet, fixed_ips=None):
+        if fixed_ips:
+            subnet_data = fixed_ips[0]['subnet_id']
+        else:
+            subnet_data = subnet
         try:
-            subnet_info = self.plugin.get_subnet(context, subnet)
+            subnet_info = self.plugin.get_subnet(
+                context, subnet_data)
         except n_exc.SubnetNotFound:
             return {}
         else:
             # retrieve the gateway port on this subnet
-            filter = {'fixed_ips': {'subnet_id': [subnet],
-                                    'ip_address': [subnet_info['gateway_ip']]}}
+            if fixed_ips:
+                filter = fixed_ips[0]
+            else:
+                filter = {'fixed_ips': {'subnet_id': [subnet],
+                                        'ip_address':
+                                        [subnet_info['gateway_ip']]}}
+
             internal_gateway_ports = self.plugin.get_ports(
                 context, filters=filter)
             if not internal_gateway_ports:
index 905c8a8e9e8868010b356c9d2504bbd4a7a9d12e..10a2dcd39384d0e15a93d3c4712b9f86078621ff 100644 (file)
@@ -373,8 +373,8 @@ class OVSDVRNeutronAgent(object):
                 return
         else:
             # set up LocalDVRSubnetMapping available for this subnet
-            subnet_info = self.plugin_rpc.get_subnet_for_dvr(self.context,
-                                                             subnet_uuid)
+            subnet_info = self.plugin_rpc.get_subnet_for_dvr(
+                self.context, subnet_uuid, fixed_ips=fixed_ips)
             if not subnet_info:
                 LOG.error(_LE("DVR: Unable to retrieve subnet information "
                               "for subnet_id %s"), subnet_uuid)
@@ -525,8 +525,8 @@ class OVSDVRNeutronAgent(object):
         if subnet_uuid not in self.local_dvr_map:
             # no csnat ports seen on this subnet - create csnat state
             # for this subnet
-            subnet_info = self.plugin_rpc.get_subnet_for_dvr(self.context,
-                                                             subnet_uuid)
+            subnet_info = self.plugin_rpc.get_subnet_for_dvr(
+                self.context, subnet_uuid, fixed_ips=fixed_ips)
             ldm = LocalDVRSubnetMapping(subnet_info, port.ofport)
             self.local_dvr_map[subnet_uuid] = ldm
         else:
index 5be1121fcd448f7c6a1f20f234fb6becc66fa35e..0931604db7b8d2c35a95047cb682210bfeb42fc3 100644 (file)
@@ -47,7 +47,9 @@ class DVRServerRpcApiTestCase(base.BaseTestCase):
             host='foo_host', subnet='foo_subnet')
 
     def test_get_subnet_for_dvr(self):
-        self.rpc.get_subnet_for_dvr(self.ctxt, 'foo_subnet')
+        self.rpc.get_subnet_for_dvr(
+            self.ctxt, 'foo_subnet', fixed_ips='foo_fixed_ips')
         self.mock_cctxt.call.assert_called_with(
             self.ctxt, 'get_subnet_for_dvr',
-            subnet='foo_subnet')
+            subnet='foo_subnet',
+            fixed_ips='foo_fixed_ips')