From fc0ae03e2198d826f8861e2d427864708fda9136 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Wed, 18 Mar 2015 13:18:25 -0700 Subject: [PATCH] VMware NSX: Fix DVR operations The switch to the community management layer mixin introduced several bugs in the NSX-mh plugins. This patch: 1) Stops creating centralized SNAT interfaces for NSX distributed routers. The NSX backend does not need those and they therefore only waste IPs and create confusion. This is done by providing an empty implementation for the relevant methods. 2) Does not query l3-agents when removing router interface. This is causing errors during interface removal and preventing router removal, as the NSX plugin does not use l3 agents at all. This patch provides an empty implementation for the relevant method thus preventing the DVR mixin from doing any sort of operations pertaining l3 agents. 3) It ensures DVR router interfaces are taken into account in the management of metadata network for routers. Applied for stackforge/vmware-nsx commit id: e248f87867a74722df243598d6a6d707170ca5ce Change-Id: I149307ff67e464e78ae393bb57c25bbee607ee4b Closes-Bug: #1433550 Closes-Bug: #1433553 Closes-Bug: #1433554 --- neutron/plugins/vmware/dhcp_meta/rpc.py | 4 ++-- neutron/plugins/vmware/plugins/base.py | 28 ++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/neutron/plugins/vmware/dhcp_meta/rpc.py b/neutron/plugins/vmware/dhcp_meta/rpc.py index ba68cef0001..c0e85ae7f29 100644 --- a/neutron/plugins/vmware/dhcp_meta/rpc.py +++ b/neutron/plugins/vmware/dhcp_meta/rpc.py @@ -23,7 +23,6 @@ from neutron.api.v2 import attributes from neutron.common import constants as const from neutron.common import exceptions as ntn_exc from neutron.db import db_base_plugin_v2 -from neutron.db import l3_db from neutron.db import models_v2 from neutron.openstack.common import log as logging from neutron.plugins.vmware.api_client import exception as api_exc @@ -96,7 +95,8 @@ def handle_router_metadata_access(plugin, context, router_id, interface=None): return ctx_elevated = context.elevated() device_filter = {'device_id': [router_id], - 'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]} + 'device_owner': [const.DEVICE_OWNER_DVR_INTERFACE, + const.DEVICE_OWNER_ROUTER_INTF]} # Retrieve ports calling database plugin ports = db_base_plugin_v2.NeutronDbPluginV2.get_ports( plugin, ctx_elevated, filters=device_filter) diff --git a/neutron/plugins/vmware/plugins/base.py b/neutron/plugins/vmware/plugins/base.py index 643dbd3ea01..b6e18c4e90f 100644 --- a/neutron/plugins/vmware/plugins/base.py +++ b/neutron/plugins/vmware/plugins/base.py @@ -83,6 +83,8 @@ NSX_NOSNAT_RULES_ORDER = 10 NSX_FLOATINGIP_NAT_RULES_ORDER = 224 NSX_EXTGW_NAT_RULES_ORDER = 255 NSX_DEFAULT_NEXTHOP = '1.1.1.1' +ROUTER_INTERFACE_OWNERS = [constants.DEVICE_OWNER_DVR_INTERFACE, + constants.DEVICE_OWNER_ROUTER_INTF] class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin, @@ -1663,6 +1665,26 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin, {'subnet_id': subnet_id, 'router_id': router_id}) return router_iface_info + def get_l3_agents_hosting_routers(self, context, routers): + # This method is just a stub added because is required by the l3 dvr + # mixin. That's so much for a management layer which is plugin + # agnostic + return [] + + def create_snat_intf_ports_if_not_exists(self, context, router): + # VMware plugins do not need SNAT interface ports + return [] + + def add_csnat_router_interface_port(self, context, router, network_id, + subnet_id, do_pop=True): + # VMware plugins do not need SNAT interface ports + return + + def delete_csnat_router_interface_ports(self, context, router, + subnet_id=None): + # VMware plugins do not need SNAT interface ports + return + def remove_router_interface(self, context, router_id, interface_info): # The code below is duplicated from base class, but comes handy # as we need to retrieve the router port id before removing the port @@ -1674,7 +1696,7 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin, port = self._get_port(context, port_id) if port.get('fixed_ips'): subnet_id = port['fixed_ips'][0]['subnet_id'] - if not (port['device_owner'] == l3_db.DEVICE_OWNER_ROUTER_INTF and + if not (port['device_owner'] in ROUTER_INTERFACE_OWNERS and port['device_id'] == router_id): raise l3.RouterInterfaceNotFound(router_id=router_id, port_id=port_id) @@ -1684,8 +1706,8 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin, rport_qry = context.session.query(models_v2.Port) ports = rport_qry.filter_by( device_id=router_id, - device_owner=l3_db.DEVICE_OWNER_ROUTER_INTF, - network_id=subnet['network_id']) + network_id=subnet['network_id']).filter( + models_v2.Port.device_owner.in_(ROUTER_INTERFACE_OWNERS)) for p in ports: if p['fixed_ips'][0]['subnet_id'] == subnet_id: port_id = p['id']