components/openstack/neutron/patches/03-l3-agent-add-solaris.patch
changeset 1760 353323c7bdc1
equal deleted inserted replaced
1759:b412ae0aa701 1760:353323c7bdc1
       
     1 In-house patch to the Neutron L3 agent to allow an alternate implementation (in
       
     2 this case, EVS) of L3 and NAT support.  This patch has not yet been
       
     3 submitted upstream.
       
     4 
       
     5 --- quantum-2013.1.4/quantum/agent/l3_agent.py.~1~	2013-10-17 11:24:18.000000000 -0700
       
     6 +++ quantum-2013.1.4/quantum/agent/l3_agent.py	2014-03-13 01:51:36.761165189 -0700
       
     7 @@ -3,6 +3,8 @@
       
     8  #
       
     9  # Copyright 2012 Nicira Networks, Inc.  All rights reserved.
       
    10  #
       
    11 +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
       
    12 +#
       
    13  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
       
    14  #    not use this file except in compliance with the License. You may obtain
       
    15  #    a copy of the License at
       
    16 @@ -16,12 +18,14 @@
       
    17  #    under the License.
       
    18  #
       
    19  # @author: Dan Wendlandt, Nicira, Inc
       
    20 +# @author: Girish Moodalbail, Oracle, Inc
       
    21  #
       
    22  """
       
    23  
       
    24  import eventlet
       
    25  from eventlet import semaphore
       
    26  import netaddr
       
    27 +import platform
       
    28  from oslo.config import cfg
       
    29  
       
    30  from quantum.agent.common import config
       
    31 @@ -31,6 +35,8 @@
       
    32  from quantum.agent.linux import iptables_manager
       
    33  from quantum.agent.linux import utils
       
    34  from quantum.agent import rpc as agent_rpc
       
    35 +from quantum.agent.solaris import ipfilters_manager
       
    36 +from quantum.agent.solaris import net_lib
       
    37  from quantum.common import constants as l3_constants
       
    38  from quantum.common import topics
       
    39  from quantum.common import utils as common_utils
       
    40 @@ -113,6 +119,8 @@
       
    41  
       
    42  class L3NATAgent(manager.Manager):
       
    43  
       
    44 +    RouterInfo = RouterInfo
       
    45 +
       
    46      OPTS = [
       
    47          cfg.StrOpt('external_network_bridge', default='br-ex',
       
    48                     help=_("Name of bridge used for external network "
       
    49 @@ -223,8 +231,8 @@
       
    50                  raise
       
    51  
       
    52      def _router_added(self, router_id, router):
       
    53 -        ri = RouterInfo(router_id, self.root_helper,
       
    54 -                        self.conf.use_namespaces, router)
       
    55 +        ri = self.RouterInfo(router_id, self.root_helper,
       
    56 +                             self.conf.use_namespaces, router)
       
    57          self.router_info[router_id] = ri
       
    58          if self.conf.use_namespaces:
       
    59              self._create_router_namespace(ri)
       
    60 @@ -303,14 +311,11 @@
       
    61          for p in new_ports:
       
    62              self._set_subnet_info(p)
       
    63              ri.internal_ports.append(p)
       
    64 -            self.internal_network_added(ri, ex_gw_port,
       
    65 -                                        p['network_id'], p['id'],
       
    66 -                                        p['ip_cidr'], p['mac_address'])
       
    67 +            self.internal_network_added(ri, ex_gw_port, p)
       
    68  
       
    69          for p in old_ports:
       
    70              ri.internal_ports.remove(p)
       
    71 -            self.internal_network_removed(ri, ex_gw_port, p['id'],
       
    72 -                                          p['ip_cidr'])
       
    73 +            self.internal_network_removed(ri, ex_gw_port, p)
       
    74  
       
    75          internal_cidrs = [p['ip_cidr'] for p in ri.internal_ports]
       
    76  
       
    77 @@ -470,16 +475,17 @@
       
    78              rules.extend(self.internal_network_nat_rules(ex_gw_ip, cidr))
       
    79          return rules
       
    80  
       
    81 -    def internal_network_added(self, ri, ex_gw_port, network_id, port_id,
       
    82 -                               internal_cidr, mac_address):
       
    83 -        interface_name = self.get_internal_device_name(port_id)
       
    84 +    def internal_network_added(self, ri, ex_gw_port, p):
       
    85 +
       
    86 +        interface_name = self.get_internal_device_name(p['id'])
       
    87          if not ip_lib.device_exists(interface_name,
       
    88                                      root_helper=self.root_helper,
       
    89                                      namespace=ri.ns_name()):
       
    90 -            self.driver.plug(network_id, port_id, interface_name, mac_address,
       
    91 +            self.driver.plug(p['network_id'], p['id'], interface_name,
       
    92 +                             p['mac_address'],
       
    93                               namespace=ri.ns_name(),
       
    94                               prefix=INTERNAL_DEV_PREFIX)
       
    95 -
       
    96 +        internal_cidr = p['ip_cidr']
       
    97          self.driver.init_l3(interface_name, [internal_cidr],
       
    98                              namespace=ri.ns_name())
       
    99          ip_address = internal_cidr.split('/')[0]
       
   100 @@ -492,8 +498,8 @@
       
   101                  ri.iptables_manager.ipv4['nat'].add_rule(c, r)
       
   102              ri.iptables_manager.apply()
       
   103  
       
   104 -    def internal_network_removed(self, ri, ex_gw_port, port_id, internal_cidr):
       
   105 -        interface_name = self.get_internal_device_name(port_id)
       
   106 +    def internal_network_removed(self, ri, ex_gw_port, p):
       
   107 +        interface_name = self.get_internal_device_name(p['id'])
       
   108          if ip_lib.device_exists(interface_name,
       
   109                                  root_helper=self.root_helper,
       
   110                                  namespace=ri.ns_name()):
       
   111 @@ -503,7 +509,7 @@
       
   112          if ex_gw_port:
       
   113              ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address']
       
   114              for c, r in self.internal_network_nat_rules(ex_gw_ip,
       
   115 -                                                        internal_cidr):
       
   116 +                                                        p['ip_cidr']):
       
   117                  ri.iptables_manager.ipv4['nat'].remove_rule(c, r)
       
   118              ri.iptables_manager.apply()
       
   119  
       
   120 @@ -742,16 +748,20 @@
       
   121  def main():
       
   122      eventlet.monkey_patch()
       
   123      conf = cfg.CONF
       
   124 -    conf.register_opts(L3NATAgent.OPTS)
       
   125      config.register_agent_state_opts_helper(conf)
       
   126      config.register_root_helper(conf)
       
   127      conf.register_opts(interface.OPTS)
       
   128      conf.register_opts(external_process.OPTS)
       
   129 +    if platform.system() == "SunOS":
       
   130 +        manager = 'quantum.agent.evs_l3_agent.EVSL3NATAgent'
       
   131 +    else:
       
   132 +        conf.register_opts(L3NATAgent.OPTS)
       
   133 +        manager = 'quantum.agent.l3_agent.L3NATAgentWithStateReport'
       
   134      conf(project='quantum')
       
   135      config.setup_logging(conf)
       
   136      server = quantum_service.Service.create(
       
   137          binary='quantum-l3-agent',
       
   138          topic=topics.L3_AGENT,
       
   139          report_interval=cfg.CONF.AGENT.report_interval,
       
   140 -        manager='quantum.agent.l3_agent.L3NATAgentWithStateReport')
       
   141 +        manager=manager)
       
   142      service.launch(server).wait()
       
   143 --- quantum-2013.1.4/quantum/db/l3_db.py.~1~	2013-10-17 11:24:18.000000000 -0700
       
   144 +++ quantum-2013.1.4/quantum/db/l3_db.py	2014-03-13 01:48:03.082634902 -0700
       
   145 @@ -2,6 +2,8 @@
       
   146  
       
   147  # Copyright 2012 Nicira Networks, Inc.  All rights reserved.
       
   148  #
       
   149 +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
       
   150 +#
       
   151  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
       
   152  #    not use this file except in compliance with the License. You may obtain
       
   153  #    a copy of the License at
       
   154 @@ -15,6 +17,7 @@
       
   155  #    under the License.
       
   156  #
       
   157  # @author: Dan Wendlandt, Nicira, Inc
       
   158 +# @author: Girish Moodalbail, Oracle, Inc
       
   159  #
       
   160  
       
   161  import netaddr
       
   162 @@ -82,6 +85,9 @@
       
   163  class L3_NAT_db_mixin(l3.RouterPluginBase):
       
   164      """Mixin class to add L3/NAT router methods to db_plugin_base_v2"""
       
   165  
       
   166 +    Router = Router
       
   167 +    FloatingIP = FloatingIP
       
   168 +
       
   169      def _network_model_hook(self, context, original_model, query):
       
   170          query = query.outerjoin(ExternalNetwork,
       
   171                                  (original_model.id ==
       
   172 @@ -117,7 +123,7 @@
       
   173  
       
   174      def _get_router(self, context, id):
       
   175          try:
       
   176 -            router = self._get_by_id(context, Router, id)
       
   177 +            router = self._get_by_id(context, self.Router, id)
       
   178          except exc.NoResultFound:
       
   179              raise l3.RouterNotFound(router_id=id)
       
   180          except exc.MultipleResultsFound:
       
   181 @@ -148,11 +154,11 @@
       
   182          with context.session.begin(subtransactions=True):
       
   183              # pre-generate id so it will be available when
       
   184              # configuring external gw port
       
   185 -            router_db = Router(id=uuidutils.generate_uuid(),
       
   186 -                               tenant_id=tenant_id,
       
   187 -                               name=r['name'],
       
   188 -                               admin_state_up=r['admin_state_up'],
       
   189 -                               status="ACTIVE")
       
   190 +            router_db = self.Router(id=uuidutils.generate_uuid(),
       
   191 +                                    tenant_id=tenant_id,
       
   192 +                                    name=r['name'],
       
   193 +                                    admin_state_up=r['admin_state_up'],
       
   194 +                                    status="ACTIVE")
       
   195              context.session.add(router_db)
       
   196              if has_gw_info:
       
   197                  self._update_router_gw_info(context, router_db['id'], gw_info)
       
   198 @@ -273,7 +279,7 @@
       
   199                      sorts=None, limit=None, marker=None,
       
   200                      page_reverse=False):
       
   201          marker_obj = self._get_marker_obj(context, 'router', limit, marker)
       
   202 -        return self._get_collection(context, Router,
       
   203 +        return self._get_collection(context, self.Router,
       
   204                                      self._make_router_dict,
       
   205                                      filters=filters, fields=fields,
       
   206                                      sorts=sorts,
       
   207 @@ -282,15 +288,14 @@
       
   208                                      page_reverse=page_reverse)
       
   209  
       
   210      def get_routers_count(self, context, filters=None):
       
   211 -        return self._get_collection_count(context, Router,
       
   212 +        return self._get_collection_count(context, self.Router,
       
   213                                            filters=filters)
       
   214  
       
   215      def _check_for_dup_router_subnet(self, context, router_id,
       
   216                                       network_id, subnet_id, subnet_cidr):
       
   217          try:
       
   218 -            rport_qry = context.session.query(models_v2.Port)
       
   219 -            rports = rport_qry.filter_by(
       
   220 -                device_id=router_id).all()
       
   221 +            rports = self.get_ports(context,
       
   222 +                                    filters={'device_id': [router_id]})
       
   223              # its possible these ports on on the same network, but
       
   224              # different subnet
       
   225              new_ipnet = netaddr.IPNetwork(subnet_cidr)
       
   226 @@ -348,8 +353,9 @@
       
   227                                                port['network_id'],
       
   228                                                subnet['id'],
       
   229                                                subnet['cidr'])
       
   230 -            port.update({'device_id': router_id,
       
   231 -                         'device_owner': DEVICE_OWNER_ROUTER_INTF})
       
   232 +            self.update_port(context, interface_info['port_id'],
       
   233 +                             {'device_id': router_id,
       
   234 +                              'device_owner': DEVICE_OWNER_ROUTER_INTF})
       
   235          elif 'subnet_id' in interface_info:
       
   236              subnet_id = interface_info['subnet_id']
       
   237              subnet = self._get_subnet(context, subnet_id)
       
   238 @@ -394,7 +400,7 @@
       
   239                                               subnet_id):
       
   240          subnet_db = self._get_subnet(context, subnet_id)
       
   241          subnet_cidr = netaddr.IPNetwork(subnet_db['cidr'])
       
   242 -        fip_qry = context.session.query(FloatingIP)
       
   243 +        fip_qry = context.session.query(self.FloatingIP)
       
   244          for fip_db in fip_qry.filter_by(router_id=router_id):
       
   245              if netaddr.IPAddress(fip_db['fixed_ip_address']) in subnet_cidr:
       
   246                  raise l3.RouterInterfaceInUseByFloatingIP(
       
   247 @@ -440,22 +446,19 @@
       
   248              subnet = self._get_subnet(context, subnet_id)
       
   249              found = False
       
   250  
       
   251 -            try:
       
   252 -                rport_qry = context.session.query(models_v2.Port)
       
   253 -                ports = rport_qry.filter_by(
       
   254 -                    device_id=router_id,
       
   255 -                    device_owner=DEVICE_OWNER_ROUTER_INTF,
       
   256 -                    network_id=subnet['network_id']).all()
       
   257 -
       
   258 -                for p in ports:
       
   259 -                    if p['fixed_ips'][0]['subnet_id'] == subnet_id:
       
   260 -                        port_id = p['id']
       
   261 -                        _network_id = p['network_id']
       
   262 -                        self.delete_port(context, p['id'], l3_port_check=False)
       
   263 -                        found = True
       
   264 -                        break
       
   265 -            except exc.NoResultFound:
       
   266 -                pass
       
   267 +            filters = {
       
   268 +                'device_id': router_id,
       
   269 +                'device_owner': DEVICE_OWNER_ROUTER_INTF,
       
   270 +                'network_id': subnet['network_id']
       
   271 +            }
       
   272 +            ports = self.get_ports(context, filters)
       
   273 +            for p in ports:
       
   274 +                if p['fixed_ips'][0]['subnet_id'] == subnet_id:
       
   275 +                    port_id = p['id']
       
   276 +                    _network_id = p['network_id']
       
   277 +                    self.delete_port(context, p['id'], l3_port_check=False)
       
   278 +                    found = True
       
   279 +                    break
       
   280  
       
   281              if not found:
       
   282                  raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id,
       
   283 @@ -477,7 +480,7 @@
       
   284  
       
   285      def _get_floatingip(self, context, id):
       
   286          try:
       
   287 -            floatingip = self._get_by_id(context, FloatingIP, id)
       
   288 +            floatingip = self._get_by_id(context, self.FloatingIP, id)
       
   289          except exc.NoResultFound:
       
   290              raise l3.FloatingIPNotFound(floatingip_id=id)
       
   291          except exc.MultipleResultsFound:
       
   292 @@ -505,19 +508,21 @@
       
   293              raise q_exc.BadRequest(resource='floatingip', msg=msg)
       
   294  
       
   295          # find router interface ports on this network
       
   296 -        router_intf_qry = context.session.query(models_v2.Port)
       
   297 -        router_intf_ports = router_intf_qry.filter_by(
       
   298 -            network_id=internal_port['network_id'],
       
   299 -            device_owner=DEVICE_OWNER_ROUTER_INTF)
       
   300 +        router_intf_filter = {
       
   301 +            'network_id': internal_port['network_id'],
       
   302 +            'device_owner': DEVICE_OWNER_ROUTER_INTF
       
   303 +        }
       
   304 +        router_intf_ports = self.get_ports(context, filters=router_intf_filter)
       
   305  
       
   306          for intf_p in router_intf_ports:
       
   307              if intf_p['fixed_ips'][0]['subnet_id'] == internal_subnet_id:
       
   308                  router_id = intf_p['device_id']
       
   309 -                router_gw_qry = context.session.query(models_v2.Port)
       
   310 -                has_gw_port = router_gw_qry.filter_by(
       
   311 -                    network_id=external_network_id,
       
   312 -                    device_id=router_id,
       
   313 -                    device_owner=DEVICE_OWNER_ROUTER_GW).count()
       
   314 +                filters = {
       
   315 +                    'network_id': external_network_id,
       
   316 +                    'device_id': router_id,
       
   317 +                    'device_owner': DEVICE_OWNER_ROUTER_GW
       
   318 +                }
       
   319 +                has_gw_port = self.get_ports_count(context, filters)
       
   320                  if has_gw_port:
       
   321                      return router_id
       
   322  
       
   323 @@ -578,13 +583,13 @@
       
   324                                                      floating_network_id)
       
   325          # confirm that this router has a floating
       
   326          # ip enabled gateway with support for this floating IP network
       
   327 -        try:
       
   328 -            port_qry = context.elevated().session.query(models_v2.Port)
       
   329 -            ports = port_qry.filter_by(
       
   330 -                network_id=floating_network_id,
       
   331 -                device_id=router_id,
       
   332 -                device_owner=DEVICE_OWNER_ROUTER_GW).one()
       
   333 -        except exc.NoResultFound:
       
   334 +        filters = {
       
   335 +            'network_id': floating_network_id,
       
   336 +            'device_id': router_id,
       
   337 +            'device_owner': DEVICE_OWNER_ROUTER_GW
       
   338 +        }
       
   339 +        ports = self.get_ports(context.elevated(), filters)
       
   340 +        if not ports:
       
   341              raise l3.ExternalGatewayForFloatingIPNotFound(
       
   342                  subnet_id=internal_subnet_id,
       
   343                  port_id=internal_port['id'])
       
   344 @@ -602,7 +607,7 @@
       
   345                  context,
       
   346                  fip,
       
   347                  floatingip_db['floating_network_id'])
       
   348 -            fip_qry = context.session.query(FloatingIP)
       
   349 +            fip_qry = context.session.query(self.FloatingIP)
       
   350              try:
       
   351                  fip_qry.filter_by(
       
   352                      fixed_port_id=fip['port_id'],
       
   353 @@ -653,7 +658,7 @@
       
   354  
       
   355                  floating_fixed_ip = external_port['fixed_ips'][0]
       
   356                  floating_ip_address = floating_fixed_ip['ip_address']
       
   357 -                floatingip_db = FloatingIP(
       
   358 +                floatingip_db = self.FloatingIP(
       
   359                      id=fip_id,
       
   360                      tenant_id=tenant_id,
       
   361                      floating_network_id=fip['floating_network_id'],
       
   362 @@ -731,7 +736,7 @@
       
   363                  if key in filters:
       
   364                      filters[val] = filters.pop(key)
       
   365  
       
   366 -        return self._get_collection(context, FloatingIP,
       
   367 +        return self._get_collection(context, self.FloatingIP,
       
   368                                      self._make_floatingip_dict,
       
   369                                      filters=filters, fields=fields,
       
   370                                      sorts=sorts,
       
   371 @@ -740,7 +745,7 @@
       
   372                                      page_reverse=page_reverse)
       
   373  
       
   374      def get_floatingips_count(self, context, filters=None):
       
   375 -        return self._get_collection_count(context, FloatingIP,
       
   376 +        return self._get_collection_count(context, self.FloatingIP,
       
   377                                            filters=filters)
       
   378  
       
   379      def prevent_l3_port_deletion(self, context, port_id):
       
   380 @@ -770,7 +775,7 @@
       
   381      def disassociate_floatingips(self, context, port_id):
       
   382          with context.session.begin(subtransactions=True):
       
   383              try:
       
   384 -                fip_qry = context.session.query(FloatingIP)
       
   385 +                fip_qry = context.session.query(self.FloatingIP)
       
   386                  floating_ip = fip_qry.filter_by(fixed_port_id=port_id).one()
       
   387                  router_id = floating_ip['router_id']
       
   388                  floating_ip.update({'fixed_port_id': None,
       
   389 @@ -874,14 +879,17 @@
       
   390                             if it is None, all of routers will be queried.
       
   391          @return: a list of dicted routers with dicted gw_port populated if any
       
   392          """
       
   393 -        router_query = context.session.query(Router)
       
   394 +        router_query = context.session.query(self.Router)
       
   395          if router_ids:
       
   396              if 1 == len(router_ids):
       
   397 -                router_query = router_query.filter(Router.id == router_ids[0])
       
   398 +                router_query = \
       
   399 +                    router_query.filter(self.Router.id == router_ids[0])
       
   400              else:
       
   401 -                router_query = router_query.filter(Router.id.in_(router_ids))
       
   402 +                router_query = \
       
   403 +                    router_query.filter(self.Router.id.in_(router_ids))
       
   404          if active is not None:
       
   405 -            router_query = router_query.filter(Router.admin_state_up == active)
       
   406 +            router_query = \
       
   407 +                router_query.filter(self.Router.admin_state_up == active)
       
   408          routers = router_query.all()
       
   409          gw_port_ids = []
       
   410          if not routers: