diff --git a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_neutron_plugin.py b/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_neutron_plugin.py
deleted file mode 100644
index abf0f80..0000000
--- a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_neutron_plugin.py
+++ /dev/null
@@ -1,708 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 Nicira Networks, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-# @author: Somik Behera, Nicira Networks, Inc.
-# @author: Brad Hall, Nicira Networks, Inc.
-# @author: Dan Wendlandt, Nicira Networks, Inc.
-# @author: Dave Lapsley, Nicira Networks, Inc.
-# @author: Aaron Rosen, Nicira Networks, Inc.
-# @author: Bob Kukura, Red Hat, Inc.
-# @author: Seetharama Ayyadevara, Freescale Semiconductor, Inc.
-
-import sys
-
-from oslo.config import cfg
-
-from neutron.agent import securitygroups_rpc as sg_rpc
-from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api
-from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api
-from neutron.api.v2 import attributes
-from neutron.common import constants as q_const
-from neutron.common import exceptions as q_exc
-from neutron.common import rpc as q_rpc
-from neutron.common import topics
-from neutron.common import utils
-from neutron.db import agents_db
-from neutron.db import agentschedulers_db
-from neutron.db import allowedaddresspairs_db as addr_pair_db
-from neutron.db import db_base_plugin_v2
-from neutron.db import dhcp_rpc_base
-from neutron.db import external_net_db
-from neutron.db import extradhcpopt_db
-from neutron.db import extraroute_db
-from neutron.db import l3_agentschedulers_db
-from neutron.db import l3_gwmode_db
-from neutron.db import l3_rpc_base
-from neutron.db import portbindings_db
-from neutron.db import quota_db  # noqa
-from neutron.db import securitygroups_rpc_base as sg_db_rpc
-from neutron.extensions import allowedaddresspairs as addr_pair
-from neutron.extensions import extra_dhcp_opt as edo_ext
-from neutron.extensions import portbindings
-from neutron.extensions import providernet as provider
-from neutron.extensions import nat
-from neutron import manager
-from neutron.openstack.common import importutils
-from neutron.openstack.common import log as logging
-from neutron.openstack.common import rpc
-from neutron.openstack.common.rpc import proxy
-from neutron.plugins.common import constants as svc_constants
-from neutron.plugins.common import utils as plugin_utils
-from neutron.plugins.openvswitch.common import config  # noqa
-from neutron.plugins.openvswitch.common import constants
-from neutron.plugins.openvswitch import ovs_db_v2
-
-
-LOG = logging.getLogger(__name__)
-
-
-class OVSRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin,
-                      l3_rpc_base.L3RpcCallbackMixin,
-                      sg_db_rpc.SecurityGroupServerRpcCallbackMixin):
-
-    # history
-    #   1.0 Initial version
-    #   1.1 Support Security Group RPC
-
-    RPC_API_VERSION = '1.1'
-
-    def __init__(self, notifier, tunnel_type):
-        self.notifier = notifier
-        self.tunnel_type = tunnel_type
-
-    def create_rpc_dispatcher(self):
-        '''Get the rpc dispatcher for this manager.
-
-        If a manager would like to set an rpc API version, or support more than
-        one class as the target of rpc messages, override this method.
-        '''
-        return q_rpc.PluginRpcDispatcher([self,
-                                          agents_db.AgentExtRpcCallback()])
-
-    @classmethod
-    def get_port_from_device(cls, device):
-        port = ovs_db_v2.get_port_from_device(device)
-        if port:
-            port['device'] = device
-        return port
-
-    def get_device_details(self, rpc_context, **kwargs):
-        """Agent requests device details."""
-        agent_id = kwargs.get('agent_id')
-        device = kwargs.get('device')
-        LOG.debug(_("Device %(device)s details requested from %(agent_id)s"),
-                  {'device': device, 'agent_id': agent_id})
-        port = ovs_db_v2.get_port(device)
-        if port:
-            binding = ovs_db_v2.get_network_binding(None, port['network_id'])
-            entry = {'device': device,
-                     'network_id': port['network_id'],
-                     'port_id': port['id'],
-                     'admin_state_up': port['admin_state_up'],
-                     'network_type': binding.network_type,
-                     'segmentation_id': binding.segmentation_id,
-                     'physical_network': binding.physical_network}
-            new_status = (q_const.PORT_STATUS_ACTIVE if port['admin_state_up']
-                          else q_const.PORT_STATUS_DOWN)
-            if port['status'] != new_status:
-                ovs_db_v2.set_port_status(port['id'], new_status)
-        else:
-            entry = {'device': device}
-            LOG.debug(_("%s can not be found in database"), device)
-        return entry
-
-    def update_device_down(self, rpc_context, **kwargs):
-        """Device no longer exists on agent."""
-        agent_id = kwargs.get('agent_id')
-        device = kwargs.get('device')
-        host = kwargs.get('host')
-        port = ovs_db_v2.get_port(device)
-        LOG.debug(_("Device %(device)s no longer exists on %(agent_id)s"),
-                  {'device': device, 'agent_id': agent_id})
-        if port:
-            entry = {'device': device,
-                     'exists': True}
-            plugin = manager.NeutronManager.get_plugin()
-            if (host and
-                not plugin.get_port_host(rpc_context, port['id']) == host):
-                LOG.debug(_("Device %(device)s not bound to the"
-                            " agent host %(host)s"),
-                          {'device': device, 'host': host})
-            elif port['status'] != q_const.PORT_STATUS_DOWN:
-                # Set port status to DOWN
-                ovs_db_v2.set_port_status(port['id'],
-                                          q_const.PORT_STATUS_DOWN)
-        else:
-            entry = {'device': device,
-                     'exists': False}
-            LOG.debug(_("%s can not be found in database"), device)
-        return entry
-
-    def update_device_up(self, rpc_context, **kwargs):
-        """Device is up on agent."""
-        agent_id = kwargs.get('agent_id')
-        device = kwargs.get('device')
-        host = kwargs.get('host')
-        port = ovs_db_v2.get_port(device)
-        LOG.debug(_("Device %(device)s up on %(agent_id)s"),
-                  {'device': device, 'agent_id': agent_id})
-        plugin = manager.NeutronManager.get_plugin()
-        if port:
-            if (host and
-                not plugin.get_port_host(rpc_context, port['id']) == host):
-                LOG.debug(_("Device %(device)s not bound to the"
-                            " agent host %(host)s"),
-                          {'device': device, 'host': host})
-                return
-            elif port['status'] != q_const.PORT_STATUS_ACTIVE:
-                ovs_db_v2.set_port_status(port['id'],
-                                          q_const.PORT_STATUS_ACTIVE)
-        else:
-            LOG.debug(_("%s can not be found in database"), device)
-
-    def tunnel_sync(self, rpc_context, **kwargs):
-        """Update new tunnel.
-
-        Updates the datbase with the tunnel IP. All listening agents will also
-        be notified about the new tunnel IP.
-        """
-        tunnel_ip = kwargs.get('tunnel_ip')
-        # Update the database with the IP
-        tunnel = ovs_db_v2.add_tunnel_endpoint(tunnel_ip)
-        tunnels = ovs_db_v2.get_tunnel_endpoints()
-        entry = dict()
-        entry['tunnels'] = tunnels
-        # Notify all other listening agents
-        self.notifier.tunnel_update(rpc_context, tunnel.ip_address,
-                                    tunnel.id, self.tunnel_type)
-        # Return the list of tunnels IP's to the agent
-        return entry
-
-
-class AgentNotifierApi(proxy.RpcProxy,
-                       sg_rpc.SecurityGroupAgentRpcApiMixin):
-    '''Agent side of the openvswitch rpc API.
-
-    API version history:
-        1.0 - Initial version.
-
-    '''
-
-    BASE_RPC_API_VERSION = '1.0'
-
-    def __init__(self, topic):
-        super(AgentNotifierApi, self).__init__(
-            topic=topic, default_version=self.BASE_RPC_API_VERSION)
-        self.topic_network_delete = topics.get_topic_name(topic,
-                                                          topics.NETWORK,
-                                                          topics.DELETE)
-        self.topic_port_update = topics.get_topic_name(topic,
-                                                       topics.PORT,
-                                                       topics.UPDATE)
-        self.topic_tunnel_update = topics.get_topic_name(topic,
-                                                         constants.TUNNEL,
-                                                         topics.UPDATE)
-
-    def network_delete(self, context, network_id):
-        self.fanout_cast(context,
-                         self.make_msg('network_delete',
-                                       network_id=network_id),
-                         topic=self.topic_network_delete)
-
-    def port_update(self, context, port, network_type, segmentation_id,
-                    physical_network):
-        self.fanout_cast(context,
-                         self.make_msg('port_update',
-                                       port=port,
-                                       network_type=network_type,
-                                       segmentation_id=segmentation_id,
-                                       physical_network=physical_network),
-                         topic=self.topic_port_update)
-
-    def tunnel_update(self, context, tunnel_ip, tunnel_id, tunnel_type):
-        self.fanout_cast(context,
-                         self.make_msg('tunnel_update',
-                                       tunnel_ip=tunnel_ip,
-                                       tunnel_id=tunnel_id,
-                                       tunnel_type=tunnel_type),
-                         topic=self.topic_tunnel_update)
-
-
-class OVSNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
-                         external_net_db.External_net_db_mixin,
-                         extraroute_db.ExtraRoute_db_mixin,
-                         l3_gwmode_db.L3_NAT_db_mixin,
-                         sg_db_rpc.SecurityGroupServerRpcMixin,
-                         l3_agentschedulers_db.L3AgentSchedulerDbMixin,
-                         agentschedulers_db.DhcpAgentSchedulerDbMixin,
-                         portbindings_db.PortBindingMixin,
-                         extradhcpopt_db.ExtraDhcpOptMixin,
-                         addr_pair_db.AllowedAddressPairsMixin):
-
-    """Implement the Neutron abstractions using Open vSwitch.
-
-    Depending on whether tunneling is enabled, either a GRE, VXLAN tunnel or
-    a new VLAN is created for each network. An agent is relied upon to
-    perform the actual OVS configuration on each host.
-
-    The provider extension is also supported. As discussed in
-    https://bugs.launchpad.net/neutron/+bug/1023156, this class could
-    be simplified, and filtering on extended attributes could be
-    handled, by adding support for extended attributes to the
-    NeutronDbPluginV2 base class. When that occurs, this class should
-    be updated to take advantage of it.
-
-    The port binding extension enables an external application relay
-    information to and from the plugin.
-    """
-
-    # This attribute specifies whether the plugin supports or not
-    # bulk/pagination/sorting operations. Name mangling is used in
-    # order to ensure it is qualified by class
-    __native_bulk_support = True
-    __native_pagination_support = True
-    __native_sorting_support = True
-
-    _supported_extension_aliases = ["provider", "external-net", "router",
-                                    "ext-gw-mode", "binding", "quotas",
-                                    "security-group", "agent", "extraroute",
-                                    "l3_agent_scheduler",
-                                    "dhcp_agent_scheduler",
-                                    "extra_dhcp_opt",
-                                    "allowed-address-pairs",
-                                    "nat"]
-
-    @property
-    def supported_extension_aliases(self):
-        if not hasattr(self, '_aliases'):
-            aliases = self._supported_extension_aliases[:]
-            sg_rpc.disable_security_group_extension_if_noop_driver(aliases)
-            self._aliases = aliases
-        return self._aliases
-
-    def __init__(self, configfile=None):
-        self.base_binding_dict = {
-            portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS,
-            portbindings.CAPABILITIES: {
-                portbindings.CAP_PORT_FILTER:
-                'security-group' in self.supported_extension_aliases}}
-        ovs_db_v2.initialize()
-        self._parse_network_vlan_ranges()
-        ovs_db_v2.sync_vlan_allocations(self.network_vlan_ranges)
-        self.tenant_network_type = cfg.CONF.OVS.tenant_network_type
-        if self.tenant_network_type not in [constants.TYPE_LOCAL,
-                                            constants.TYPE_VLAN,
-                                            constants.TYPE_GRE,
-                                            constants.TYPE_VXLAN,
-                                            constants.TYPE_NONE]:
-            LOG.error(_("Invalid tenant_network_type: %s. "
-                      "Server terminated!"),
-                      self.tenant_network_type)
-            sys.exit(1)
-        self.enable_tunneling = cfg.CONF.OVS.enable_tunneling
-        self.tunnel_type = None
-        if self.enable_tunneling:
-            self.tunnel_type = cfg.CONF.OVS.tunnel_type or constants.TYPE_GRE
-        elif cfg.CONF.OVS.tunnel_type:
-            self.tunnel_type = cfg.CONF.OVS.tunnel_type
-            self.enable_tunneling = True
-        self.tunnel_id_ranges = []
-        if self.enable_tunneling:
-            self._parse_tunnel_id_ranges()
-            ovs_db_v2.sync_tunnel_allocations(self.tunnel_id_ranges)
-        elif self.tenant_network_type in constants.TUNNEL_NETWORK_TYPES:
-            LOG.error(_("Tunneling disabled but tenant_network_type is '%s'. "
-                      "Server terminated!"), self.tenant_network_type)
-            sys.exit(1)
-        self.setup_rpc()
-        self.network_scheduler = importutils.import_object(
-            cfg.CONF.network_scheduler_driver
-        )
-        self.router_scheduler = importutils.import_object(
-            cfg.CONF.router_scheduler_driver
-        )
-
-    def setup_rpc(self):
-        # RPC support
-        self.service_topics = {svc_constants.CORE: topics.PLUGIN,
-                               svc_constants.L3_ROUTER_NAT: topics.L3PLUGIN}
-        self.conn = rpc.create_connection(new=True)
-        self.notifier = AgentNotifierApi(topics.AGENT)
-        self.agent_notifiers[q_const.AGENT_TYPE_DHCP] = (
-            dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
-        )
-        self.agent_notifiers[q_const.AGENT_TYPE_L3] = (
-            l3_rpc_agent_api.L3AgentNotify
-        )
-        self.callbacks = OVSRpcCallbacks(self.notifier, self.tunnel_type)
-        self.dispatcher = self.callbacks.create_rpc_dispatcher()
-        for svc_topic in self.service_topics.values():
-            self.conn.create_consumer(svc_topic, self.dispatcher, fanout=False)
-        # Consume from all consumers in a thread
-        self.conn.consume_in_thread()
-
-    def _parse_network_vlan_ranges(self):
-        try:
-            self.network_vlan_ranges = plugin_utils.parse_network_vlan_ranges(
-                cfg.CONF.OVS.network_vlan_ranges)
-        except Exception as ex:
-            LOG.error(_("%s. Server terminated!"), ex)
-            sys.exit(1)
-        LOG.info(_("Network VLAN ranges: %s"), self.network_vlan_ranges)
-
-    def _parse_tunnel_id_ranges(self):
-        for entry in cfg.CONF.OVS.tunnel_id_ranges:
-            entry = entry.strip()
-            try:
-                tun_min, tun_max = entry.split(':')
-                self.tunnel_id_ranges.append((int(tun_min), int(tun_max)))
-            except ValueError as ex:
-                LOG.error(_("Invalid tunnel ID range: "
-                            "'%(range)s' - %(e)s. Server terminated!"),
-                          {'range': entry, 'e': ex})
-                sys.exit(1)
-        LOG.info(_("Tunnel ID ranges: %s"), self.tunnel_id_ranges)
-
-    def _extend_network_dict_provider(self, context, network):
-        binding = ovs_db_v2.get_network_binding(context.session,
-                                                network['id'])
-        network[provider.NETWORK_TYPE] = binding.network_type
-        if binding.network_type in constants.TUNNEL_NETWORK_TYPES:
-            network[provider.PHYSICAL_NETWORK] = None
-            network[provider.SEGMENTATION_ID] = binding.segmentation_id
-        elif binding.network_type == constants.TYPE_FLAT:
-            network[provider.PHYSICAL_NETWORK] = binding.physical_network
-            network[provider.SEGMENTATION_ID] = None
-        elif binding.network_type == constants.TYPE_VLAN:
-            network[provider.PHYSICAL_NETWORK] = binding.physical_network
-            network[provider.SEGMENTATION_ID] = binding.segmentation_id
-        elif binding.network_type == constants.TYPE_LOCAL:
-            network[provider.PHYSICAL_NETWORK] = None
-            network[provider.SEGMENTATION_ID] = None
-
-    def _process_provider_create(self, context, attrs):
-        network_type = attrs.get(provider.NETWORK_TYPE)
-        physical_network = attrs.get(provider.PHYSICAL_NETWORK)
-        segmentation_id = attrs.get(provider.SEGMENTATION_ID)
-
-        network_type_set = attributes.is_attr_set(network_type)
-        physical_network_set = attributes.is_attr_set(physical_network)
-        segmentation_id_set = attributes.is_attr_set(segmentation_id)
-
-        if not (network_type_set or physical_network_set or
-                segmentation_id_set):
-            return (None, None, None)
-
-        if not network_type_set:
-            msg = _("provider:network_type required")
-            raise q_exc.InvalidInput(error_message=msg)
-        elif network_type == constants.TYPE_FLAT:
-            if segmentation_id_set:
-                msg = _("provider:segmentation_id specified for flat network")
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                segmentation_id = constants.FLAT_VLAN_ID
-        elif network_type == constants.TYPE_VLAN:
-            if not segmentation_id_set:
-                msg = _("provider:segmentation_id required")
-                raise q_exc.InvalidInput(error_message=msg)
-            if not utils.is_valid_vlan_tag(segmentation_id):
-                msg = (_("provider:segmentation_id out of range "
-                         "(%(min_id)s through %(max_id)s)") %
-                       {'min_id': q_const.MIN_VLAN_TAG,
-                        'max_id': q_const.MAX_VLAN_TAG})
-                raise q_exc.InvalidInput(error_message=msg)
-        elif network_type in constants.TUNNEL_NETWORK_TYPES:
-            if not self.enable_tunneling:
-                msg = _("%s networks are not enabled") % network_type
-                raise q_exc.InvalidInput(error_message=msg)
-            if physical_network_set:
-                msg = _("provider:physical_network specified for %s "
-                        "network") % network_type
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                physical_network = None
-            if not segmentation_id_set:
-                msg = _("provider:segmentation_id required")
-                raise q_exc.InvalidInput(error_message=msg)
-        elif network_type == constants.TYPE_LOCAL:
-            if physical_network_set:
-                msg = _("provider:physical_network specified for local "
-                        "network")
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                physical_network = None
-            if segmentation_id_set:
-                msg = _("provider:segmentation_id specified for local "
-                        "network")
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                segmentation_id = None
-        else:
-            msg = _("provider:network_type %s not supported") % network_type
-            raise q_exc.InvalidInput(error_message=msg)
-
-        if network_type in [constants.TYPE_VLAN, constants.TYPE_FLAT]:
-            if physical_network_set:
-                if physical_network not in self.network_vlan_ranges:
-                    msg = _("Unknown provider:physical_network "
-                            "%s") % physical_network
-                    raise q_exc.InvalidInput(error_message=msg)
-            elif 'default' in self.network_vlan_ranges:
-                physical_network = 'default'
-            else:
-                msg = _("provider:physical_network required")
-                raise q_exc.InvalidInput(error_message=msg)
-
-        return (network_type, physical_network, segmentation_id)
-
-    def create_network(self, context, network):
-        (network_type, physical_network,
-         segmentation_id) = self._process_provider_create(context,
-                                                          network['network'])
-
-        session = context.session
-        #set up default security groups
-        tenant_id = self._get_tenant_id_for_create(
-            context, network['network'])
-        self._ensure_default_security_group(context, tenant_id)
-
-        with session.begin(subtransactions=True):
-            if not network_type:
-                # tenant network
-                network_type = self.tenant_network_type
-                if network_type == constants.TYPE_NONE:
-                    raise q_exc.TenantNetworksDisabled()
-                elif network_type == constants.TYPE_VLAN:
-                    (physical_network,
-                     segmentation_id) = ovs_db_v2.reserve_vlan(session)
-                elif network_type in constants.TUNNEL_NETWORK_TYPES:
-                    segmentation_id = ovs_db_v2.reserve_tunnel(session)
-                # no reservation needed for TYPE_LOCAL
-            else:
-                # provider network
-                if network_type in [constants.TYPE_VLAN, constants.TYPE_FLAT]:
-                    ovs_db_v2.reserve_specific_vlan(session, physical_network,
-                                                    segmentation_id)
-                elif network_type in constants.TUNNEL_NETWORK_TYPES:
-                    ovs_db_v2.reserve_specific_tunnel(session, segmentation_id)
-                # no reservation needed for TYPE_LOCAL
-            net = super(OVSNeutronPluginV2, self).create_network(context,
-                                                                 network)
-            ovs_db_v2.add_network_binding(session, net['id'], network_type,
-                                          physical_network, segmentation_id)
-
-            self._process_l3_create(context, net, network['network'])
-            self._extend_network_dict_provider(context, net)
-            # note - exception will rollback entire transaction
-        LOG.debug(_("Created network: %s"), net['id'])
-        return net
-
-    def update_network(self, context, id, network):
-        provider._raise_if_updates_provider_attributes(network['network'])
-
-        session = context.session
-        with session.begin(subtransactions=True):
-            net = super(OVSNeutronPluginV2, self).update_network(context, id,
-                                                                 network)
-            self._process_l3_update(context, net, network['network'])
-            self._extend_network_dict_provider(context, net)
-        return net
-
-    def delete_network(self, context, id):
-        session = context.session
-        with session.begin(subtransactions=True):
-            binding = ovs_db_v2.get_network_binding(session, id)
-            super(OVSNeutronPluginV2, self).delete_network(context, id)
-            if binding.network_type in constants.TUNNEL_NETWORK_TYPES:
-                ovs_db_v2.release_tunnel(session, binding.segmentation_id,
-                                         self.tunnel_id_ranges)
-            elif binding.network_type in [constants.TYPE_VLAN,
-                                          constants.TYPE_FLAT]:
-                ovs_db_v2.release_vlan(session, binding.physical_network,
-                                       binding.segmentation_id,
-                                       self.network_vlan_ranges)
-            # the network_binding record is deleted via cascade from
-            # the network record, so explicit removal is not necessary
-        self.notifier.network_delete(context, id)
-
-    def get_network(self, context, id, fields=None):
-        session = context.session
-        with session.begin(subtransactions=True):
-            net = super(OVSNeutronPluginV2, self).get_network(context,
-                                                              id, None)
-            self._extend_network_dict_provider(context, net)
-        return self._fields(net, fields)
-
-    def get_networks(self, context, filters=None, fields=None,
-                     sorts=None,
-                     limit=None, marker=None, page_reverse=False):
-        session = context.session
-        with session.begin(subtransactions=True):
-            nets = super(OVSNeutronPluginV2,
-                         self).get_networks(context, filters, None, sorts,
-                                            limit, marker, page_reverse)
-            for net in nets:
-                self._extend_network_dict_provider(context, net)
-
-        return [self._fields(net, fields) for net in nets]
-
-    def create_port(self, context, port):
-        # Set port status as 'DOWN'. This will be updated by agent
-        port['port']['status'] = q_const.PORT_STATUS_DOWN
-        port_data = port['port']
-        session = context.session
-        with session.begin(subtransactions=True):
-            self._ensure_default_security_group_on_port(context, port)
-            sgids = self._get_security_groups_on_port(context, port)
-            dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
-            port = super(OVSNeutronPluginV2, self).create_port(context, port)
-            self._process_portbindings_create_and_update(context,
-                                                         port_data, port)
-            self._process_port_create_security_group(context, port, sgids)
-            self._process_port_create_extra_dhcp_opts(context, port,
-                                                      dhcp_opts)
-            port[addr_pair.ADDRESS_PAIRS] = (
-                self._process_create_allowed_address_pairs(
-                    context, port,
-                    port_data.get(addr_pair.ADDRESS_PAIRS)))
-        self.notify_security_groups_member_updated(context, port)
-        return port
-
-    def _extend_port_dict_nat(self, context, port):
-        forward = ovs_db_v2.get_port_forwarding(context.session, port['id'])
-        if forward:
-            port[nat.FORWARD_PORTS] = forward
-        else:
-            port[nat.FORWARD_PORTS] = None
-
-    def _process_nat_update(self, context, attrs, id):
-        forward_ports = attrs.get(nat.FORWARD_PORTS)
-        forward_ports_set = attributes.is_attr_set(forward_ports)
-
-        if not forward_ports_set:
-            return None
-
-        # LOG.info("forward ports %s" % forward_ports)
-        valid_protocols = ["tcp", "udp"]
-        for entry in forward_ports:
-            if not isinstance(entry, dict):
-                msg = _("nat:forward_ports: must specify a list of dicts (ex: 'l4_protocol=tcp,l4_port=80')")
-                raise q_exc.InvalidInput(error_message=msg)
-            if not ("l4_protocol" in entry and "l4_port" in entry):
-                msg = _("nat:forward_ports: dict is missing l4_protocol and l4_port (ex: 'l4_protocol=tcp,l4_port=80')")
-                raise q_exc.InvalidInput(error_message=msg)
-            if entry['l4_protocol'] not in valid_protocols:
-                msg = _("nat:forward_ports: invalid protocol (only tcp and udp allowed)")
-                raise q_exc.InvalidInput(error_message=msg)
-
-            l4_port = entry['l4_port']
-            if ":" in l4_port:
-                try:
-                    (first, last) = l4_port.split(":")
-                    first = int(first)
-                    last = int(last)
-                except:
-                    msg = _("nat:forward_ports: l4_port range must be integer:integer")
-                    raise q_exc.InvalidInput(error_message=msg)
-            else:
-                try:
-                    l4_port = int(l4_port)
-                except:
-                    msg = _("nat:forward_ports: l4_port must be an integer")
-                    raise q_exc.InvalidInput(error_message=msg)
-
-        return forward_ports
-
-    def get_port(self, context, id, fields=None):
-        session = context.session
-        with session.begin(subtransactions=True):
-            port = super(OVSNeutronPluginV2, self).get_port(context, id, None)
-            self._extend_port_dict_nat(context, port)
-        return self._fields(port, fields)
-
-    def get_ports(self, context, filters=None, fields=None):
-        session = context.session
-        with session.begin(subtransactions=True):
-            ports = super(OVSNeutronPluginV2, self).get_ports(context, filters,
-                                                          None)
-            for port in ports:
-                self._extend_port_dict_nat(context, port)
-
-        return [self._fields(port, fields) for port in ports]
-
-    def update_port(self, context, id, port):
-        forward_ports = self._process_nat_update(context, port['port'], id)
-
-        session = context.session
-        need_port_update_notify = False
-        changed_fixed_ips = 'fixed_ips' in port['port']
-        with session.begin(subtransactions=True):
-            original_port = super(OVSNeutronPluginV2, self).get_port(
-                context, id)
-            updated_port = super(OVSNeutronPluginV2, self).update_port(
-                context, id, port)
-            if addr_pair.ADDRESS_PAIRS in port['port']:
-                self._delete_allowed_address_pairs(context, id)
-                self._process_create_allowed_address_pairs(
-                    context, updated_port,
-                    port['port'][addr_pair.ADDRESS_PAIRS])
-                need_port_update_notify = True
-            elif changed_fixed_ips:
-                self._check_fixed_ips_and_address_pairs_no_overlap(
-                    context, updated_port)
-
-            if forward_ports:
-                ovs_db_v2.clear_port_forwarding(session, updated_port['id'])
-                ovs_db_v2.add_port_forwarding(session, updated_port['id'], forward_ports)
-            self._extend_port_dict_nat(context, updated_port)
-
-            need_port_update_notify |= self.update_security_group_on_port(
-                context, id, port, original_port, updated_port)
-            self._process_portbindings_create_and_update(context,
-                                                         port['port'],
-                                                         updated_port)
-            need_port_update_notify |= self._update_extra_dhcp_opts_on_port(
-                context, id, port, updated_port)
-
-        need_port_update_notify |= self.is_security_group_member_updated(
-            context, original_port, updated_port)
-        if original_port['admin_state_up'] != updated_port['admin_state_up']:
-            need_port_update_notify = True
-
-        if need_port_update_notify:
-            binding = ovs_db_v2.get_network_binding(None,
-                                                    updated_port['network_id'])
-            self.notifier.port_update(context, updated_port,
-                                      binding.network_type,
-                                      binding.segmentation_id,
-                                      binding.physical_network)
-        return updated_port
-
-    def delete_port(self, context, id, l3_port_check=True):
-
-        # if needed, check to see if this is a port owned by
-        # and l3-router.  If so, we should prevent deletion.
-        if l3_port_check:
-            self.prevent_l3_port_deletion(context, id)
-
-        session = context.session
-        with session.begin(subtransactions=True):
-            self.disassociate_floatingips(context, id)
-            port = self.get_port(context, id)
-            self._delete_port_security_group_bindings(context, id)
-            super(OVSNeutronPluginV2, self).delete_port(context, id)
-
-        self.notify_security_groups_member_updated(context, port)
