From: Swaminathan Vasudevan Date: Wed, 29 Apr 2015 05:50:31 +0000 (-0700) Subject: Fix gateway port could not retrieve for subnet X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=e82b0e108332964c90e9d2cfaf3d334a92127155;p=openstack-build%2Fneutron-build.git Fix gateway port could not retrieve for subnet 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 --- diff --git a/neutron/api/rpc/handlers/dvr_rpc.py b/neutron/api/rpc/handlers/dvr_rpc.py index 8b6574707..02909b6f7 100644 --- a/neutron/api/rpc/handlers/dvr_rpc.py +++ b/neutron/api/rpc/handlers/dvr_rpc.py @@ -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): diff --git a/neutron/db/dvr_mac_db.py b/neutron/db/dvr_mac_db.py index c0f0d656a..8ec13042b 100644 --- a/neutron/db/dvr_mac_db.py +++ b/neutron/db/dvr_mac_db.py @@ -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: diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py index 905c8a8e9..10a2dcd39 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py @@ -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: diff --git a/neutron/tests/unit/api/rpc/handlers/test_dvr_rpc.py b/neutron/tests/unit/api/rpc/handlers/test_dvr_rpc.py index 5be1121fc..0931604db 100644 --- a/neutron/tests/unit/api/rpc/handlers/test_dvr_rpc.py +++ b/neutron/tests/unit/api/rpc/handlers/test_dvr_rpc.py @@ -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')