def add_csnat_router_interface_port(self, context, router, network_id, subnet_id, do_pop=True): """Add SNAT interface to the specified router and subnet.""" snat_port = self._core_plugin.create_port( context, { 'port': { 'tenant_id': '', 'network_id': network_id, 'mac_address': attributes.ATTR_NOT_SPECIFIED, 'fixed_ips': [{ 'subnet_id': subnet_id }], 'device_id': router.id, 'device_owner': DEVICE_OWNER_DVR_SNAT, 'admin_state_up': True, 'name': '' } }) if not snat_port: msg = _("Unable to create the SNAT Interface Port") raise n_exc.BadRequest(resource='router', msg=msg) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort(port_id=snat_port['id'], router_id=router.id, port_type=DEVICE_OWNER_DVR_SNAT) context.session.add(router_port) if do_pop: return self._populate_subnet_for_ports(context, [snat_port]) return snat_port
def add_router_port(self, context, port_id, router_id): with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort( port_id=port_id, router_id=router_id, port_type=q_const.DEVICE_OWNER_ROUTER_INTF) context.session.add(router_port)
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) if add_by_port: port = self._add_interface_by_port(context, router, interface_info['port_id'], device_owner) elif add_by_sub: port = self._add_interface_by_subnet(context, router, interface_info['subnet_id'], device_owner) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort(port_id=port['id'], router_id=router.id, port_type=device_owner) context.session.add(router_port) if router.extra_attributes.distributed and router.gw_port: self.add_csnat_router_interface_port( context.elevated(), router, port['network_id'], port['fixed_ips'][0]['subnet_id']) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], port['fixed_ips'][0]['subnet_id']) self.notify_router_interface_action(context, router_interface_info, 'add') return router_interface_info
def _add_csnat_router_interface_port( self, context, router, network_id, subnet_id, do_pop=True): """Add SNAT interface to the specified router and subnet.""" port_data = {'tenant_id': '', 'network_id': network_id, 'fixed_ips': [{'subnet_id': subnet_id}], 'device_id': router.id, 'device_owner': l3_const.DEVICE_OWNER_ROUTER_SNAT, 'admin_state_up': True, 'name': ''} snat_port = p_utils.create_port(self._core_plugin, context, {'port': port_data}) if not snat_port: msg = _("Unable to create the SNAT Interface Port") raise n_exc.BadRequest(resource='router', msg=msg) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort( port_id=snat_port['id'], router_id=router.id, port_type=l3_const.DEVICE_OWNER_ROUTER_SNAT ) context.session.add(router_port) if do_pop: return self._populate_mtu_and_subnets_for_ports(context, [snat_port]) return snat_port
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) # This should be True unless adding an IPv6 prefix to an existing port new_port = True if add_by_port: port, subnets = self._add_interface_by_port( context, router, interface_info['port_id'], device_owner) elif add_by_sub: port, subnets, new_port = self._add_interface_by_subnet( context, router, interface_info['subnet_id'], device_owner) if new_port: with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort(port_id=port['id'], router_id=router.id, port_type=device_owner) context.session.add(router_port) if router.extra_attributes.distributed and router.gw_port: self._add_csnat_router_interface_port( context.elevated(), router, port['network_id'], port['fixed_ips'][-1]['subnet_id']) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], subnets[-1]['id'], [subnet['id'] for subnet in subnets]) self.notify_router_interface_action(context, router_interface_info, 'add') return router_interface_info
def _create_router_gw_port(self, context, router, network_id, ext_ips): # Port has no 'tenant-id', as it is hidden from user gw_port = self._core_plugin.create_port( context.elevated(), { 'port': { 'tenant_id': '', # intentionally not set 'network_id': network_id, 'mac_address': q_const.ATTR_NOT_SPECIFIED, 'fixed_ips': ext_ips or q_const.ATTR_NOT_SPECIFIED, 'device_id': router['id'], 'device_owner': l3_db.DEVICE_OWNER_ROUTER_GW, 'admin_state_up': True, 'status': q_const.PORT_STATUS_ACTIVE, 'name': '' } }) if not gw_port['fixed_ips']: LOG.debug('No IPs available for external network %s', network_id) with context.session.begin(subtransactions=True): router.gw_port = self._core_plugin._get_port( context.elevated(), gw_port['id']) router_port = l3_db.RouterPort( router_id=router.id, port_id=gw_port['id'], port_type=l3_db.DEVICE_OWNER_ROUTER_GW) context.session.add(router) context.session.add(router_port)
def _create_auxiliary_external_gateway_port( self, context, global_router, ext_net_id, tenant_router, port_type=DEVICE_OWNER_GLOBAL_ROUTER_GW): # When a global router is connected to an external network then a # special type of gateway port is created on that network. Such a # port is called auxiliary gateway ports. A (logical) global router # never has a traditional Neutron gateway port. filters = { 'device_id': [tenant_router['id']], 'device_owner': [l3_constants.DEVICE_OWNER_ROUTER_GW]} # fetch the gateway port of the *tenant* router so we can determine # the CIDR of that port's subnet gw_port = self._core_plugin.get_ports(context, filters=filters)[0] fixed_ips = self._get_fixed_ips_subnets(gw_port['fixed_ips']) global_router_id = global_router['id'] with context.session.begin(subtransactions=True): aux_gw_port = self._core_plugin.create_port(context, { 'port': { 'tenant_id': '', # intentionally not set 'network_id': ext_net_id, 'mac_address': bc.constants.ATTR_NOT_SPECIFIED, 'fixed_ips': fixed_ips, 'device_id': global_router_id, 'device_owner': port_type, 'admin_state_up': True, 'name': ''}}) router_port = l3_db.RouterPort( port_id=aux_gw_port['id'], router_id=global_router_id, port_type=port_type) context.session.add(router_port) return aux_gw_port
def _create_router_gw_port(self, context, router, network_id, ext_ips): if ext_ips and len(ext_ips) > 1: msg = _("Routers support only 1 external IP") raise q_exc.BadRequest(resource='router', msg=msg) gw_port = self._core_plugin.create_port( context.elevated(), { 'port': { 'tenant_id': config.VROUTER.tenant_id, 'network_id': network_id, 'mac_address': attributes.ATTR_NOT_SPECIFIED, 'fixed_ips': ext_ips or attributes.ATTR_NOT_SPECIFIED, 'device_owner': '', 'device_id': '', 'admin_state_up': True, 'name': '', psec.PORTSECURITY: False, } }) if not gw_port['fixed_ips']: self._core_plugin.delete_port(context.elevated(), gw_port['id'], l3_port_check=False) msg = (_('No IPs available for external network %s') % network_id) raise q_exc.BadRequest(resource='router', msg=msg) with context.session.begin(subtransactions=True): router.gw_port = self._core_plugin._get_port( context.elevated(), gw_port['id']) router_port = l3_db.RouterPort( router_id=router.id, port_id=gw_port['id'], port_type=l3_constants.DEVICE_OWNER_ROUTER_GW) context.session.add(router) context.session.add(router_port) try: self._attach_port(context, router['id'], gw_port, external_gw=True) except Exception as ex: LOG.exception(_LE("Exception while attaching port : %s"), ex) with excutils.save_and_reraise_exception(): try: with context.session.begin(subtransactions=True): router.gw_port = None context.session.add(router) self._core_plugin.delete_port(context.elevated(), gw_port['id']) except Exception: LOG.exception( _LE('Failed to roll back changes to ' 'Vyatta vRouter after external ' 'gateway assignment.'))
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) # This should be True unless adding an IPv6 prefix to an existing port new_port = True if add_by_port: port, subnets = self._add_interface_by_port( context, router, interface_info['port_id'], device_owner) elif add_by_sub: port, subnets, new_port = self._add_interface_by_subnet( context, router, interface_info['subnet_id'], device_owner) if new_port: if router.extra_attributes.distributed and router.gw_port: try: admin_context = context.elevated() self._add_csnat_router_interface_port( admin_context, router, port['network_id'], port['fixed_ips'][-1]['subnet_id']) except Exception: with excutils.save_and_reraise_exception(): # we need to preserve the original state prior # the request by rolling back the port creation # that led to new_port=True self._core_plugin.delete_port(admin_context, port['id']) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort(port_id=port['id'], router_id=router.id, port_type=device_owner) context.session.add(router_port) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], subnets[-1]['id'], [subnet['id'] for subnet in subnets]) self.notify_router_interface_action(context, router_interface_info, 'add') return router_interface_info
def _create_router_gw_port(self, context, router, network_id, ext_ips): # Port has no 'tenant-id', as it is hidden from user LOG.debug("Class OVNL3RouterPlugin:::") gw_port = self._core_plugin.create_port( context.elevated(), { 'port': { 'tenant_id': router['tenant_id'], 'network_id': network_id, 'mac_address': attributes.ATTR_NOT_SPECIFIED, 'fixed_ips': attributes.ATTR_NOT_SPECIFIED, 'device_id': router['id'], 'device_owner': l3_db.DEVICE_OWNER_ROUTER_GW, 'admin_state_up': True, 'name': 'Extnet_' + router['name'][0:18] } }) if not gw_port['fixed_ips']: self._core_plugin.delete_port(context.elevated(), gw_port['id'], l3_port_check=False) msg = (_('No IPs available for external network %s') % network_id) raise n_exc.BadRequest(resource='router', msg=msg) try: self.create_gw_router_port_in_ovn(context, router['id'], gw_port) except Exception: self._core_plugin.delete_port(context.elevated(), gw_port['id'], l3_port_check=False) self.delete_gw_router_port_in_ovn(router['id'], gw_port['id']) LOG.exception(_LE('Fail to update gateway info for router %s'), router['id']) raise n_exc.ServiceUnavailable() with context.session.begin(subtransactions=True): router.gw_port = self._core_plugin._get_port( context.elevated(), gw_port['id']) router_port = l3_db.RouterPort( router_id=router.id, port_id=gw_port['id'], port_type=l3_db.DEVICE_OWNER_ROUTER_GW) context.session.add(router) context.session.add(router_port)
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) if add_by_port: port = self._add_interface_by_port(context, router, interface_info['port_id'], device_owner) elif add_by_sub: # ###add by xm at 2015.9.1 for bug 6061 ---begin--- # if 'name' in interface_info and interface_info['name'] is not None: # name = interface_info['name'] # else: # name = '' # ###end # port = self._add_interface_by_subnet( # context, router, interface_info['subnet_id'], device_owner, name) port = self._add_interface_by_subnet(context, router, interface_info['subnet_id'], device_owner) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort( port_id=port['id'], router_id=router.id, port_type=device_owner, subnet_id=port['fixed_ips'][0]['subnet_id']) context.session.add(router_port) if router.extra_attributes.distributed and router.gw_port: self.add_csnat_router_interface_port( context.elevated(), router, port['network_id'], port['fixed_ips'][0]['subnet_id']) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], port['fixed_ips'][0]['subnet_id']) self.notify_router_interface_action(context, router_interface_info, 'add') return router_interface_info
def _create_ha_port_binding(self, context, router_id, port_id): try: with context.session.begin(): routerportbinding = l3_db.RouterPort( port_id=port_id, router_id=router_id, port_type=constants.DEVICE_OWNER_ROUTER_HA_INTF) context.session.add(routerportbinding) portbinding = L3HARouterAgentPortBinding(port_id=port_id, router_id=router_id) context.session.add(portbinding) return portbinding except db_exc.DBReferenceError as e: with excutils.save_and_reraise_exception() as ctxt: if isinstance(e.inner_exception, sql_exc.IntegrityError): ctxt.reraise = False LOG.debug( 'Failed to create HA router agent PortBinding, ' 'Router %s has already been removed ' 'by concurrent operation', router_id) raise l3.RouterNotFound(router_id=router_id)
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) # This should be True unless adding an IPv6 prefix to an existing port new_port = True if add_by_port: port, subnets = self._add_interface_by_port( context, router, interface_info['port_id'], device_owner) elif add_by_sub: port, subnets, new_port = self._add_interface_by_subnet( context, router, interface_info['subnet_id'], device_owner) subnet = subnets[0] if new_port: if router.extra_attributes.distributed and router.gw_port: try: admin_context = context.elevated() self._add_csnat_router_interface_port( admin_context, router, port['network_id'], port['fixed_ips'][-1]['subnet_id']) except Exception: with excutils.save_and_reraise_exception(): # we need to preserve the original state prior # the request by rolling back the port creation # that led to new_port=True self._core_plugin.delete_port( admin_context, port['id']) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort( port_id=port['id'], router_id=router.id, port_type=device_owner ) context.session.add(router_port) # NOTE: For IPv6 additional subnets added to the same # network we need to update the CSNAT port with respective # IPv6 subnet elif subnet and port: fixed_ip = {'subnet_id': subnet['id']} if subnet['ip_version'] == 6: # Add new prefix to an existing ipv6 csnat port with the # same network id if one exists cs_port = self._find_router_port_by_network_and_device_owner( router, subnet['network_id'], l3_const.DEVICE_OWNER_ROUTER_SNAT) if cs_port: fixed_ips = list(cs_port['port']['fixed_ips']) fixed_ips.append(fixed_ip) updated_port = self._core_plugin.update_port( context.elevated(), cs_port['port_id'], {'port': {'fixed_ips': fixed_ips}}) LOG.debug("CSNAT port updated for IPv6 subnet: " "%s", updated_port) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], port['network_id'], subnet['id'], [subnet['id']]) self.notify_router_interface_action( context, router_interface_info, 'add') return router_interface_info
def add_router_interface(self, context, router_id, interface_info): LOG.debug( "Vyatta vRouter Plugin::Add Router Interface. " "router: %s; interface: %s", router_id, interface_info) add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) new_port = True if add_by_port: port, subnets = self._add_interface_by_port( context, router, interface_info['port_id'], '') elif add_by_sub: port, subnets, new_port = self._add_interface_by_subnet( context, router, interface_info['subnet_id'], '') if new_port: port_tenant_id = port['tenant_id'] self._core_plugin._delete_port_security_group_bindings( context.elevated(), port['id']) port = self._core_plugin.update_port( context.elevated(), port['id'], { 'port': { 'tenant_id': config.VROUTER.tenant_id, 'device_id': '', psec.PORTSECURITY: False, } }) try: self._attach_port(context, router_id, port) except Exception: with excutils.save_and_reraise_exception(): if add_by_sub: try: self._core_plugin.delete_port( context.elevated(), port['id']) except Exception: LOG.exception( _LE('Failed to delete previously created ' 'port for Vyatta vRouter.')) port = self._core_plugin.update_port( context.elevated(), port['id'], {'port': { 'tenant_id': port_tenant_id, }}) with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort(port_id=port['id'], router_id=router.id, port_type=port['device_owner']) context.session.add(router_port) else: self._update_port(context, router_id, port) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], subnets[-1]['id'], [subnet['id'] for subnet in subnets]) self.notify_router_interface_action(context, router_interface_info, 'add') return router_interface_info
def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) device_owner = self._get_device_owner(context, router) # This should be True unless adding an IPv6 prefix to an existing port new_port = True cleanup_port = False if add_by_port: port, subnets = self._add_interface_by_port( context, router, interface_info['port_id'], device_owner) elif add_by_sub: port, subnets, new_port = self._add_interface_by_subnet( context, router, interface_info['subnet_id'], device_owner) cleanup_port = new_port subnet = subnets[0] if new_port: with p_utils.delete_port_on_error(self._core_plugin, context, port['id']) as delmgr: if router.extra_attributes.distributed and router.gw_port: admin_context = context.elevated() self._add_csnat_router_interface_port( admin_context, router, port['network_id'], port['fixed_ips'][-1]['subnet_id']) delmgr.delete_on_error = cleanup_port with context.session.begin(subtransactions=True): router_port = l3_db.RouterPort(port_id=port['id'], router_id=router.id, port_type=device_owner) context.session.add(router_port) # NOTE: For IPv6 additional subnets added to the same # network we need to update the CSNAT port with respective # IPv6 subnet elif subnet and port: fixed_ip = {'subnet_id': subnet['id']} if subnet['ip_version'] == 6: # Add new prefix to an existing ipv6 csnat port with the # same network id if one exists cs_port = ( self._find_v6_router_port_by_network_and_device_owner( router, subnet['network_id'], const.DEVICE_OWNER_ROUTER_SNAT)) if cs_port: fixed_ips = list(cs_port['port']['fixed_ips']) fixed_ips.append(fixed_ip) updated_port = self._core_plugin.update_port( context.elevated(), cs_port['port_id'], {'port': { 'fixed_ips': fixed_ips }}) LOG.debug("CSNAT port updated for IPv6 subnet: " "%s", updated_port) router_interface_info = self._make_router_interface_info( router_id, port['tenant_id'], port['id'], port['network_id'], subnet['id'], [subnet['id']]) self.notify_router_interface_action(context, router_interface_info, 'add') if router.gw_port: gw_network_id = router.gw_port.network_id gw_ips = [x['ip_address'] for x in router.gw_port.fixed_ips] registry.notify(resources.ROUTER_INTERFACE, events.AFTER_CREATE, self, context=context, network_id=gw_network_id, gateway_ips=gw_ips, cidrs=[x['cidr'] for x in subnets], port_id=port['id'], router_id=router_id, port=port, interface_info=interface_info) return router_interface_info