def _notify_l3_agent_port_update(resource, event, trigger, **kwargs): new_port = kwargs.get('port') original_port = kwargs.get('original_port') if new_port and original_port: original_device_owner = original_port.get('device_owner', '') new_device_owner = new_port.get('device_owner', '') is_port_no_longer_serviced = ( n_utils.is_dvr_serviced(original_device_owner) and not n_utils.is_dvr_serviced(new_device_owner)) is_port_moved = ( original_port['binding:host_id'] and original_port['binding:host_id'] != new_port['binding:host_id']) if is_port_no_longer_serviced or is_port_moved: l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) context = kwargs['context'] removed_routers = l3plugin.dvr_deletens_if_no_port( context, original_port['id'], port_host=original_port['binding:host_id']) if removed_routers: removed_router_args = { 'context': context, 'port': original_port, 'removed_routers': removed_routers, } _notify_port_delete( event, resource, trigger, **removed_router_args) if not n_utils.is_dvr_serviced(new_device_owner): return _notify_l3_agent_new_port(resource, event, trigger, **kwargs)
def _notify_l3_agent_port_update(resource, event, trigger, **kwargs): new_port = kwargs.get('port') original_port = kwargs.get('original_port') if new_port and original_port: original_device_owner = original_port.get('device_owner', '') new_device_owner = new_port.get('device_owner', '') is_new_device_dvr_serviced = n_utils.is_dvr_serviced(new_device_owner) l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) context = kwargs['context'] is_port_no_longer_serviced = ( n_utils.is_dvr_serviced(original_device_owner) and not n_utils.is_dvr_serviced(new_device_owner)) is_port_moved = ( original_port[portbindings.HOST_ID] and original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID]) if is_port_no_longer_serviced or is_port_moved: removed_routers = l3plugin.get_dvr_routers_to_remove( context, original_port) if removed_routers: removed_router_args = { 'context': context, 'port': original_port, 'removed_routers': removed_routers, } _notify_port_delete( event, resource, trigger, **removed_router_args) if not is_new_device_dvr_serviced: return is_fixed_ips_changed = ( 'fixed_ips' in new_port and 'fixed_ips' in original_port and new_port['fixed_ips'] != original_port['fixed_ips']) is_new_port_binding_changed = ( new_port[portbindings.HOST_ID] and (original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID])) dest_host = None new_port_profile = new_port.get(portbindings.PROFILE) if new_port_profile: dest_host = new_port_profile.get('migrating_to') # If dest_host is set, then the port profile has changed # and this port is in migration. The call below will # pre-create the router on the new host if ((is_new_port_binding_changed or dest_host) and is_new_device_dvr_serviced): l3plugin.dvr_handle_new_service_port(context, new_port, dest_host=dest_host) l3plugin.update_arp_entry_for_dvr_service_port( context, new_port) elif kwargs.get('mac_address_updated') or is_fixed_ips_changed: l3plugin.update_arp_entry_for_dvr_service_port( context, new_port)
def _notify_l3_agent_port_update(resource, event, trigger, **kwargs): new_port = kwargs.get('port') original_port = kwargs.get('original_port') if new_port and original_port: original_device_owner = original_port.get('device_owner', '') new_device_owner = new_port.get('device_owner', '') l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) context = kwargs['context'] is_port_no_longer_serviced = ( n_utils.is_dvr_serviced(original_device_owner) and not n_utils.is_dvr_serviced(new_device_owner)) is_port_moved = ( original_port[portbindings.HOST_ID] and original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID]) if is_port_no_longer_serviced or is_port_moved: removed_routers = l3plugin.dvr_deletens_if_no_port( context, original_port['id'], port_host=original_port[portbindings.HOST_ID]) if removed_routers: removed_router_args = { 'context': context, 'port': original_port, 'removed_routers': removed_routers, } _notify_port_delete( event, resource, trigger, **removed_router_args) if not n_utils.is_dvr_serviced(new_device_owner): return is_fixed_ips_changed = ( 'fixed_ips' in new_port and 'fixed_ips' in original_port and new_port['fixed_ips'] != original_port['fixed_ips']) is_new_port_binding_changed = ( new_port[portbindings.HOST_ID] and (original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID])) if (is_new_port_binding_changed and n_utils.is_dvr_serviced(new_device_owner)): l3plugin.dvr_handle_new_service_port(context, new_port) l3plugin.update_arp_entry_for_dvr_service_port( context, new_port) elif kwargs.get('mac_address_updated') or is_fixed_ips_changed: l3plugin.update_arp_entry_for_dvr_service_port( context, new_port)
def update_unbound_allowed_address_pair_port_binding( self, context, service_port_dict, port_address_pairs, address_pair_port=None): """Update allowed address pair port with host and device_owner This function sets the host and device_owner to the port associated with the port_addr_pair_ip with the port_dict's host and device_owner. """ port_addr_pair_ip = port_address_pairs['ip_address'] if not address_pair_port: address_pair_port = self._get_address_pair_active_port_with_fip( context, service_port_dict, port_addr_pair_ip) if address_pair_port: host = service_port_dict[portbindings.HOST_ID] dev_owner = service_port_dict['device_owner'] address_pair_dev_owner = address_pair_port.get('device_owner') # If the allowed_address_pair port already has an associated # device owner, and if the device_owner is a dvr serviceable # port, then don't update the device_owner. port_profile = address_pair_port.get(portbindings.PROFILE, {}) if n_utils.is_dvr_serviced(address_pair_dev_owner): port_profile['original_owner'] = address_pair_dev_owner port_data = {portbindings.HOST_ID: host, portbindings.PROFILE: port_profile} else: port_data = {portbindings.HOST_ID: host, 'device_owner': dev_owner} update_port = self._core_plugin.update_port( context, address_pair_port['id'], {'port': port_data}) return update_port
def bind_port_to_dvr(self, port, local_vlan_map, fixed_ips, device_owner): if not self.in_distributed_mode(): return if local_vlan_map.network_type not in (constants.TUNNEL_NETWORK_TYPES + [p_const.TYPE_VLAN]): LOG.debug("DVR: Port %s is with network_type %s not supported" " for dvr plumbing" % (port.vif_id, local_vlan_map.network_type)) return if device_owner == n_const.DEVICE_OWNER_DVR_INTERFACE: self._bind_distributed_router_interface_port(port, local_vlan_map, fixed_ips, device_owner) if device_owner and n_utils.is_dvr_serviced(device_owner): self._bind_port_on_dvr_subnet(port, local_vlan_map, fixed_ips, device_owner) if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT: self._bind_centralized_snat_port_on_dvr_subnet(port, local_vlan_map, fixed_ips, device_owner)
def _get_dvr_service_port_hostid(self, context, port_id, port=None): """Returns the portbinding host_id for dvr service port.""" port_db = port or self._core_plugin.get_port(context, port_id) device_owner = port_db['device_owner'] if port_db else "" if (n_utils.is_dvr_serviced(device_owner) or device_owner == l3_const.DEVICE_OWNER_AGENT_GW): return port_db[portbindings.HOST_ID]
def check_ports_exist_on_l3agent(self, context, l3_agent, router_id): """ This function checks for existence of dvr serviceable ports on the host, running the input l3agent. """ subnet_ids = self.get_subnet_ids_on_router(context, router_id) if not subnet_ids: return False core_plugin = manager.NeutronManager.get_plugin() # NOTE(swami):Before checking for existence of dvr # serviceable ports on the host managed by the l3 # agent, let's verify if at least one subnet has # dhcp enabled. If so, then the host will have a # dvr serviceable port, which is in fact the DHCP # port. # This optimization is valid assuming that the L3 # DVR_SNAT node will be the one hosting the DHCP # Agent. agent_conf = self.get_configuration_dict(l3_agent) agent_mode = agent_conf.get(constants.L3_AGENT_MODE, constants.L3_AGENT_MODE_LEGACY) for subnet_id in subnet_ids: subnet_dict = core_plugin.get_subnet(context, subnet_id) if subnet_dict["enable_dhcp"] and (agent_mode == constants.L3_AGENT_MODE_DVR_SNAT): return True filter = {"fixed_ips": {"subnet_id": subnet_ids}} ports = core_plugin.get_ports(context, filters=filter) for port in ports: if n_utils.is_dvr_serviced(port["device_owner"]) and l3_agent["host"] == port["binding:host_id"]: return True return False
def dvr_vmarp_table_update(self, context, port_dict, action): """Notify L3 agents of VM ARP table changes. When a VM goes up or down, look for one DVR router on the port's subnet, and send the VM's ARP details to all L3 agents hosting the router. """ # Check this is a valid VM or service port if not (n_utils.is_dvr_serviced(port_dict['device_owner']) and port_dict['fixed_ips']): return ip_address = port_dict['fixed_ips'][0]['ip_address'] subnet = port_dict['fixed_ips'][0]['subnet_id'] filters = {'fixed_ips': {'subnet_id': [subnet]}} ports = self._core_plugin.get_ports(context, filters=filters) for port in ports: if port['device_owner'] == l3_const.DEVICE_OWNER_DVR_INTERFACE: router_id = port['device_id'] router_dict = self._get_router(context, router_id) if router_dict.extra_attributes.distributed: arp_table = { 'ip_address': ip_address, 'mac_address': port_dict['mac_address'], 'subnet_id': subnet } if action == "add": notify_action = self.l3_rpc_notifier.add_arp_entry elif action == "del": notify_action = self.l3_rpc_notifier.del_arp_entry notify_action(context, router_id, arp_table) return
def unbind_router_servicenode(self, context, router_id, binding): """Unbind the router from the chosen l3 service agent.""" port_found = False with context.session.begin(subtransactions=True): host = binding.l3_agent.host subnet_ids = self.get_subnet_ids_on_router(context, router_id) for subnet in subnet_ids: ports = ( self._core_plugin.get_ports_on_host_by_subnet( context, host, subnet)) for port in ports: if (n_utils.is_dvr_serviced(port['device_owner'])): port_found = True LOG.debug('One or more ports exist on the snat ' 'enabled l3_agent host %(host)s and ' 'router_id %(id)s', {'host': host, 'id': router_id}) break agent_id = binding.l3_agent_id if not port_found: context.session.query( l3agent_sch_db.RouterL3AgentBinding).filter_by( router_id=router_id, l3_agent_id=agent_id).delete( synchronize_session=False) if not port_found: self.l3_rpc_notifier.router_removed_from_agent( context, router_id, host) LOG.debug('Removed binding for router %(router_id)s and ' 'agent %(agent_id)s', {'router_id': router_id, 'agent_id': agent_id}) return port_found
def get_ports_on_host_by_subnet(self, context, host, subnet): """Returns DVR serviced ports on a given subnet in the input host This method returns ports that need to be serviced by DVR. :param context: rpc request context :param host: host id to match and extract ports of interest :param subnet: subnet id to match and extract ports of interest :returns list -- Ports on the given subnet in the input host """ # FIXME(vivek, salv-orlando): improve this query by adding the # capability of filtering by binding:host_id ports_by_host = [] filter = {'fixed_ips': {'subnet_id': [subnet]}} ports = self.plugin.get_ports(context, filters=filter) LOG.debug("List of Ports on subnet %(subnet)s at host %(host)s " "received as %(ports)s", {'subnet': subnet, 'host': host, 'ports': ports}) for port in ports: device_owner = port['device_owner'] if (utils.is_dvr_serviced(device_owner)): if port[portbindings.HOST_ID] == host: port_dict = self.plugin._make_port_dict(port, process_extensions=False) ports_by_host.append(port_dict) LOG.debug("Returning list of dvr serviced ports on host %(host)s" " for subnet %(subnet)s ports %(ports)s", {'host': host, 'subnet': subnet, 'ports': ports_by_host}) return ports_by_host
def check_ports_exist_on_l3agent( self, context, l3_agent, subnet_ids): """ This function checks for existence of dvr serviceable ports on the host, running the input l3agent. """ core_plugin = manager.NeutronManager.get_plugin() # NOTE(swami):Before checking for existence of dvr # serviceable ports on the host managed by the l3 # agent, let's verify if at least one subnet has # dhcp enabled. If so, then the host will have a # dvr serviceable port, which is in fact the DHCP # port. # This optimization is valid assuming that the L3 # DVR_SNAT node will be the one hosting the DHCP # Agent. agent_mode = self._get_agent_mode(l3_agent) for subnet_id in subnet_ids: subnet_dict = core_plugin.get_subnet(context, subnet_id) if (subnet_dict['enable_dhcp'] and ( agent_mode == constants.L3_AGENT_MODE_DVR_SNAT)): return True filter = {'fixed_ips': {'subnet_id': subnet_ids}} ports = core_plugin.get_ports(context, filters=filter) for port in ports: if (n_utils.is_dvr_serviced(port['device_owner']) and l3_agent['host'] == port['binding:host_id']): return True return False
def get_ports_on_host_by_subnet(self, context, host, subnet): """Returns ports of interest, on a given subnet in the input host This method returns ports that need to be serviced by DVR. :param context: rpc request context :param host: host id to match and extract ports of interest :param subnet: subnet id to match and extract ports of interest :returns list -- Ports on the given subnet in the input host """ # FIXME(vivek, salv-orlando): improve this query by adding the # capability of filtering by binding:host_id ports_by_host = [] filter = {'fixed_ips': {'subnet_id': [subnet]}} ports = self.plugin.get_ports(context, filters=filter) LOG.debug("List of Ports on subnet %(subnet)s at host %(host)s " "received as %(ports)s", {'subnet': subnet, 'host': host, 'ports': ports}) for port in ports: device_owner = port['device_owner'] if (utils.is_dvr_serviced(device_owner)): if port[portbindings.HOST_ID] == host: port_dict = self.plugin._make_port_dict(port, process_extensions=False) ports_by_host.append(port_dict) LOG.debug("Returning list of dvr serviced ports on host %(host)s" " for subnet %(subnet)s ports %(ports)s", {'host': host, 'subnet': subnet, 'ports': ports_by_host}) return ports_by_host
def get_vm_port_hostid(self, context, port_id, port=None): """Return the portbinding host_id.""" vm_port_db = port or self._core_plugin.get_port(context, port_id) device_owner = vm_port_db['device_owner'] if vm_port_db else "" if (n_utils.is_dvr_serviced(device_owner) or device_owner == DEVICE_OWNER_AGENT_GW): return vm_port_db[portbindings.HOST_ID]
def bind_port_to_dvr(self, port, local_vlan_map, fixed_ips, device_owner): if not self.in_distributed_mode(): return if local_vlan_map.network_type not in (constants.TUNNEL_NETWORK_TYPES + [p_const.TYPE_VLAN]): LOG.debug("DVR: Port %s is with network_type %s not supported" " for dvr plumbing", port.vif_id, local_vlan_map.network_type) return if (port.vif_id in self.local_ports and self.local_ports[port.vif_id].ofport != port.ofport): LOG.info(_LI("DVR: Port %(vif)s changed port number to " "%(ofport)s, rebinding."), {'vif': port.vif_id, 'ofport': port.ofport}) self.unbind_port_from_dvr(port, local_vlan_map) if device_owner == n_const.DEVICE_OWNER_DVR_INTERFACE: self._bind_distributed_router_interface_port(port, local_vlan_map, fixed_ips, device_owner) if device_owner and n_utils.is_dvr_serviced(device_owner): self._bind_port_on_dvr_subnet(port, local_vlan_map, fixed_ips, device_owner) if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT: self._bind_centralized_snat_port_on_dvr_subnet(port, local_vlan_map, fixed_ips, device_owner)
def update_unbound_allowed_address_pair_port_binding( self, context, service_port_dict, port_address_pairs): """Update allowed address pair port with host and device_owner This function sets the host and device_owner to the port associated with the port_addr_pair_ip with the port_dict's host and device_owner. """ port_addr_pair_ip = port_address_pairs['ip_address'] address_pair_port = self._get_address_pair_active_port_with_fip( context, service_port_dict, port_addr_pair_ip) if address_pair_port: host = service_port_dict[portbindings.HOST_ID] dev_owner = service_port_dict['device_owner'] address_pair_dev_owner = address_pair_port.get('device_owner') # If the allowed_address_pair port already has an associated # device owner, and if the device_owner is a dvr serviceable # port, then don't update the device_owner. port_profile = address_pair_port.get(portbindings.PROFILE, {}) if n_utils.is_dvr_serviced(address_pair_dev_owner): port_profile['original_owner'] = address_pair_dev_owner port_data = { portbindings.HOST_ID: host, portbindings.PROFILE: port_profile } else: port_data = { portbindings.HOST_ID: host, 'device_owner': dev_owner } update_port = self._core_plugin.update_port( context, address_pair_port['id'], {'port': port_data}) return update_port
def dvr_vmarp_table_update(self, context, port_dict, action): """Notify L3 agents of VM ARP table changes. When a VM goes up or down, look for one DVR router on the port's subnet, and send the VM's ARP details to all L3 agents hosting the router. """ # Check this is a valid VM or service port if not (n_utils.is_dvr_serviced(port_dict['device_owner']) and port_dict['fixed_ips']): return ip_address = port_dict['fixed_ips'][0]['ip_address'] subnet = port_dict['fixed_ips'][0]['subnet_id'] filters = {'fixed_ips': {'subnet_id': [subnet]}} ports = self._core_plugin.get_ports(context, filters=filters) for port in ports: if port['device_owner'] == l3_const.DEVICE_OWNER_DVR_INTERFACE: router_id = port['device_id'] router_dict = self._get_router(context, router_id) if router_dict.extra_attributes.distributed: arp_table = {'ip_address': ip_address, 'mac_address': port_dict['mac_address'], 'subnet_id': subnet} if action == "add": notify_action = self.l3_rpc_notifier.add_arp_entry elif action == "del": notify_action = self.l3_rpc_notifier.del_arp_entry notify_action(context, router_id, arp_table) return
def _notify_l3_agent_port_update(resource, event, trigger, **kwargs): new_port = kwargs.get('port') original_port = kwargs.get('original_port') if new_port and original_port: original_device_owner = original_port.get('device_owner', '') new_device_owner = new_port.get('device_owner', '') l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) context = kwargs['context'] is_port_no_longer_serviced = ( n_utils.is_dvr_serviced(original_device_owner) and not n_utils.is_dvr_serviced(new_device_owner)) is_port_moved = (original_port[portbindings.HOST_ID] and original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID]) if is_port_no_longer_serviced or is_port_moved: removed_routers = l3plugin.dvr_deletens_if_no_port( context, original_port['id'], port_host=original_port[portbindings.HOST_ID]) if removed_routers: removed_router_args = { 'context': context, 'port': original_port, 'removed_routers': removed_routers, } _notify_port_delete(event, resource, trigger, **removed_router_args) if not n_utils.is_dvr_serviced(new_device_owner): return is_fixed_ips_changed = ( 'fixed_ips' in new_port and 'fixed_ips' in original_port and new_port['fixed_ips'] != original_port['fixed_ips']) is_new_port_binding_changed = (new_port[portbindings.HOST_ID] and (original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID])) if (is_new_port_binding_changed and n_utils.is_dvr_serviced(new_device_owner)): l3plugin.dvr_handle_new_service_port(context, new_port) l3plugin.update_arp_entry_for_dvr_service_port( context, new_port, "add") elif kwargs.get('mac_address_updated') or is_fixed_ips_changed: l3plugin.update_arp_entry_for_dvr_service_port( context, new_port, "add")
def get_dvr_routers_to_remove(self, context, deleted_port): """Returns info about which routers should be removed In case dvr serviceable port was deleted we need to check if any dvr routers should be removed from l3 agent on port's host """ if not n_utils.is_dvr_serviced(deleted_port['device_owner']): return [] admin_context = context.elevated() port_host = deleted_port[portbindings.HOST_ID] subnet_ids = [ip['subnet_id'] for ip in deleted_port['fixed_ips']] router_ids = self.get_dvr_routers_by_subnet_ids(admin_context, subnet_ids) if not router_ids: LOG.debug('No DVR routers for this DVR port %(port)s ' 'on host %(host)s', {'port': deleted_port['id'], 'host': port_host}) return [] agent = self._get_agent_by_type_and_host( context, n_const.AGENT_TYPE_L3, port_host) removed_router_info = [] for router_id in router_ids: snat_binding = context.session.query( l3agent_sch_db.RouterL3AgentBinding).filter_by( router_id=router_id).filter_by( l3_agent_id=agent.id).first() if snat_binding: # not removing from the agent hosting SNAT for the router continue subnet_ids = self.get_subnet_ids_on_router(admin_context, router_id) if self._check_dvr_serviceable_ports_on_host( admin_context, port_host, subnet_ids): continue filter_rtr = {'device_id': [router_id], 'device_owner': [n_const.DEVICE_OWNER_DVR_INTERFACE]} int_ports = self._core_plugin.get_ports( admin_context, filters=filter_rtr) for port in int_ports: dvr_binding = (ml2_db. get_dvr_port_binding_by_host(context.session, port['id'], port_host)) if dvr_binding: # unbind this port from router dvr_binding['router_id'] = None dvr_binding.update(dvr_binding) info = {'router_id': router_id, 'host': port_host, 'agent_id': str(agent.id)} removed_router_info.append(info) LOG.debug('Router %(router_id)s on host %(host)s to be deleted', info) return removed_router_info
def get_dvr_routers_to_remove(self, context, deleted_port): """Returns info about which routers should be removed In case dvr serviceable port was deleted we need to check if any dvr routers should be removed from l3 agent on port's host """ if not n_utils.is_dvr_serviced(deleted_port['device_owner']): return [] admin_context = context.elevated() port_host = deleted_port[portbindings.HOST_ID] subnet_ids = [ip['subnet_id'] for ip in deleted_port['fixed_ips']] router_ids = self.get_dvr_routers_by_subnet_ids(admin_context, subnet_ids) if not router_ids: LOG.debug('No DVR routers for this DVR port %(port)s ' 'on host %(host)s', {'port': deleted_port['id'], 'host': port_host}) return [] agent = self._get_agent_by_type_and_host( context, n_const.AGENT_TYPE_L3, port_host) removed_router_info = [] for router_id in router_ids: snat_binding = context.session.query( rb_model.RouterL3AgentBinding).filter_by( router_id=router_id).filter_by( l3_agent_id=agent.id).first() if snat_binding: # not removing from the agent hosting SNAT for the router continue subnet_ids = self.get_subnet_ids_on_router(admin_context, router_id) if self._check_dvr_serviceable_ports_on_host( admin_context, port_host, subnet_ids): continue filter_rtr = {'device_id': [router_id], 'device_owner': [n_const.DEVICE_OWNER_DVR_INTERFACE]} int_ports = self._core_plugin.get_ports( admin_context, filters=filter_rtr) for port in int_ports: dvr_binding = (ml2_db. get_distributed_port_binding_by_host( context.session, port['id'], port_host)) if dvr_binding: # unbind this port from router dvr_binding['router_id'] = None dvr_binding.update(dvr_binding) info = {'router_id': router_id, 'host': port_host, 'agent_id': str(agent.id)} removed_router_info.append(info) LOG.debug('Router %(router_id)s on host %(host)s to be deleted', info) return removed_router_info
def _get_dvr_migrating_service_port_hostid( self, context, port_id, port=None): """Returns the migrating host_id from the migrating profile.""" port_db = port or self._core_plugin.get_port(context, port_id) port_profile = port_db.get(portbindings.PROFILE) port_dest_host = None if port_profile: port_dest_host = port_profile.get('migrating_to') device_owner = port_db['device_owner'] if port_db else "" if n_utils.is_dvr_serviced(device_owner): return port_dest_host
def get_vm_port_hostid(self, context, port_id, port=None): """Return the portbinding host_id.""" try: vm_port_db = port or self._core_plugin.get_port(context, port_id) except n_exc.PortNotFound: LOG.warn(_("Attempted to get hostid of port %s which was deleted"), port_id) return None device_owner = vm_port_db['device_owner'] if vm_port_db else "" if (n_utils.is_dvr_serviced(device_owner) or device_owner == DEVICE_OWNER_AGENT_GW): return vm_port_db[portbindings.HOST_ID]
def _notify_l3_agent_new_port(resource, event, trigger, **kwargs): LOG.debug('Received %(resource)s %(event)s', { 'resource': resource, 'event': event}) port = kwargs.get('port') if not port: return if n_utils.is_dvr_serviced(port['device_owner']): l3plugin = directory.get_plugin(plugin_constants.L3) context = kwargs['context'] l3plugin.dvr_handle_new_service_port(context, port)
def _notify_l3_agent_new_port(resource, event, trigger, **kwargs): LOG.debug('Received %(resource)s %(event)s', { 'resource': resource, 'event': event}) port = kwargs.get('port') if not port: return if n_utils.is_dvr_serviced(port['device_owner']): l3plugin = directory.get_plugin(plugin_constants.L3) context = kwargs['context'] l3plugin.dvr_handle_new_service_port(context, port) l3plugin.update_arp_entry_for_dvr_service_port(context, port)
def check_ports_active_on_host_and_subnet(self, context, host, port_id, subnet_id): """Check if there is any dvr serviceable port on the subnet_id.""" filter_sub = {'fixed_ips': {'subnet_id': [subnet_id]}} ports = self._core_plugin.get_ports(context, filters=filter_sub) for port in ports: if (n_utils.is_dvr_serviced(port['device_owner']) and port['binding:host_id'] == host and port['id'] != port_id): LOG.debug('DVR: Active port exists for subnet %(subnet_id)s ' 'on host %(host)s', {'subnet_id': subnet_id, 'host': host}) return True return False
def _notify_l3_agent_new_port(resource, event, trigger, payload=None): LOG.debug('Received %(resource)s %(event)s', { 'resource': resource, 'event': event }) port = payload.latest_state if not port: return if n_utils.is_dvr_serviced(port['device_owner']): l3plugin = directory.get_plugin(plugin_constants.L3) context = payload.context l3plugin.dvr_handle_new_service_port(context, port) l3plugin.update_arp_entry_for_dvr_service_port(context, port)
def _notify_l3_agent_new_port(resource, event, trigger, **kwargs): LOG.debug('Received %(resource)s %(event)s', { 'resource': resource, 'event': event}) port = kwargs.get('port') if not port: return if n_utils.is_dvr_serviced(port['device_owner']): l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) context = kwargs['context'] l3plugin.dvr_handle_new_service_port(context, port) l3plugin.update_arp_entry_for_dvr_service_port(context, port, "add")
def _notify_l3_agent_new_port(resource, event, trigger, **kwargs): LOG.debug('Received %(resource)s %(event)s', { 'resource': resource, 'event': event}) port = kwargs.get('port') if not port: return if n_utils.is_dvr_serviced(port['device_owner']): l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) context = kwargs['context'] l3plugin.dvr_update_router_addvm(context, port) l3plugin.dvr_vmarp_table_update(context, port, "add")
def check_ports_on_host_and_subnet(self, context, host, port_id, subnet_id): """Check if there are any dvr service ports on the subnet_id.""" filter_sub = {'fixed_ips': {'subnet_id': [subnet_id]}} ports = self._core_plugin.get_ports(context, filters=filter_sub) for port in ports: if (n_utils.is_dvr_serviced(port['device_owner']) and port[portbindings.HOST_ID] == host and port['id'] != port_id): LOG.debug('DVR: %(port_status)s port exists for subnet ' '%(subnet_id)s on host %(host)s', {'port_status': port['status'], 'subnet_id': subnet_id, 'host': host}) return True return False
def check_ports_active_on_host_and_subnet(self, context, host, port_id, subnet_id): """Check if there is any dvr serviceable port on the subnet_id.""" filter_sub = {'fixed_ips': {'subnet_id': [subnet_id]}} ports = self._core_plugin.get_ports(context, filters=filter_sub) for port in ports: if (n_utils.is_dvr_serviced(port['device_owner']) and port['status'] == 'ACTIVE' and port['binding:host_id'] == host and port['id'] != port_id): LOG.debug('DVR: Active port exists for subnet %(subnet_id)s ' 'on host %(host)s', {'subnet_id': subnet_id, 'host': host}) return True return False
def _notify_l3_agent_new_port(resource, event, trigger, **kwargs): LOG.debug('Received %s %s' % (resource, event)) port = kwargs['port'] if not port: return l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) mac_address_updated = kwargs.get('mac_address_updated') update_device_up = kwargs.get('update_device_up') context = kwargs['context'] if mac_address_updated or update_device_up: l3plugin.dvr_vmarp_table_update(context, port, "add") if n_utils.is_dvr_serviced(port['device_owner']): l3plugin.dvr_update_router_addvm(context, port)
def check_ports_exist_on_l3agent(self, context, l3_agent, router_id): """ This function checks for existence of dvr serviceable ports on the host, running the input l3agent. """ subnet_ids = self.get_subnet_ids_on_router(context, router_id) core_plugin = manager.NeutronManager.get_plugin() filter = {'fixed_ips': {'subnet_id': subnet_ids}} ports = core_plugin.get_ports(context, filters=filter) for port in ports: if (n_utils.is_dvr_serviced(port['device_owner']) and l3_agent['host'] == port['binding:host_id']): return True return False
def check_ports_active_on_host_and_subnet(self, context, host, port_id, subnet_id): """Check if there is any dvr serviceable port on the subnet_id.""" filter_sub = {"fixed_ips": {"subnet_id": [subnet_id]}} ports = self._core_plugin.get_ports(context, filters=filter_sub) for port in ports: if ( n_utils.is_dvr_serviced(port["device_owner"]) and port["status"] == "ACTIVE" and port["binding:host_id"] == host and port["id"] != port_id ): LOG.debug( "DVR: Active port exists for subnet %(subnet_id)s " "on host %(host)s", {"subnet_id": subnet_id, "host": host}, ) return True return False
def check_ports_on_host_and_subnet(self, context, host, port_id, subnet_id): """Check if there are any dvr service ports on the subnet_id.""" filter_sub = {'fixed_ips': {'subnet_id': [subnet_id]}} ports = self._core_plugin.get_ports(context, filters=filter_sub) for port in ports: if (n_utils.is_dvr_serviced(port['device_owner']) and port[portbindings.HOST_ID] == host and port['id'] != port_id): LOG.debug( 'DVR: %(port_status)s port exists for subnet ' '%(subnet_id)s on host %(host)s', { 'port_status': port['status'], 'subnet_id': subnet_id, 'host': host }) return True return False
def bind_port_to_dvr(self, port, network_type, fixed_ips, device_owner, local_vlan_id): if not self.in_distributed_mode(): return if network_type not in constants.TUNNEL_NETWORK_TYPES: return if device_owner == n_const.DEVICE_OWNER_DVR_INTERFACE: self._bind_distributed_router_interface_port( port, fixed_ips, device_owner, local_vlan_id) if device_owner and n_utils.is_dvr_serviced(device_owner): self._bind_port_on_dvr_subnet(port, fixed_ips, device_owner, local_vlan_id) if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT: self._bind_centralized_snat_port_on_dvr_subnet( port, fixed_ips, device_owner, local_vlan_id)
def unbind_port_from_dvr(self, vif_port, local_vlan_map): if not self.in_distributed_mode(): return # Handle port removed use-case if vif_port and vif_port.vif_id not in self.local_ports: LOG.debug("DVR: Non distributed port, ignoring %s", vif_port) return ovsport = self.local_ports[vif_port.vif_id] device_owner = ovsport.get_device_owner() if device_owner == n_const.DEVICE_OWNER_DVR_INTERFACE: self._unbind_distributed_router_interface_port(vif_port, local_vlan_map) if device_owner and n_utils.is_dvr_serviced(device_owner): self._unbind_port_on_dvr_subnet(vif_port, local_vlan_map) if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT: self._unbind_centralized_snat_port_on_dvr_subnet(vif_port, local_vlan_map)
def unbind_port_from_dvr(self, vif_port, local_vlan_map): if not self.in_distributed_mode(): return # Handle port removed use-case if vif_port and vif_port.vif_id not in self.local_ports: LOG.debug("DVR: Non distributed port, ignoring %s", vif_port) return ovsport = self.local_ports[vif_port.vif_id] device_owner = ovsport.get_device_owner() if device_owner == n_const.DEVICE_OWNER_DVR_INTERFACE: self._unbind_distributed_router_interface_port( vif_port, local_vlan_map) if device_owner and n_utils.is_dvr_serviced(device_owner): self._unbind_port_on_dvr_subnet(vif_port, local_vlan_map) if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT: self._unbind_centralized_snat_port_on_dvr_subnet( vif_port, local_vlan_map)
def bind_port_to_dvr(self, port, network_type, fixed_ips, device_owner, local_vlan_id): if not self.in_distributed_mode(): return if network_type not in constants.TUNNEL_NETWORK_TYPES: return if device_owner == n_const.DEVICE_OWNER_DVR_INTERFACE: self._bind_distributed_router_interface_port(port, fixed_ips, device_owner, local_vlan_id) if device_owner and n_utils.is_dvr_serviced(device_owner): self._bind_port_on_dvr_subnet(port, fixed_ips, device_owner, local_vlan_id) if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT: self._bind_centralized_snat_port_on_dvr_subnet(port, fixed_ips, device_owner, local_vlan_id)
def update_arp_entry_for_dvr_service_port( self, context, port_dict, action): """Notify L3 agents of ARP table entry for dvr service port. When a dvr service port goes up or down, look for the DVR router on the port's subnet, and send the ARP details to all L3 agents hosting the router. """ # Check this is a valid VM or service port if not (n_utils.is_dvr_serviced(port_dict['device_owner']) and port_dict['fixed_ips']): return changed_fixed_ips = port_dict['fixed_ips'] for fixed_ip in changed_fixed_ips: if action == "add": notifier = self.l3_rpc_notifier.add_arp_entry elif action == "del": notifier = self.l3_rpc_notifier.del_arp_entry else: return self._generate_arp_table_and_notify_agent( context, fixed_ip, port_dict['mac_address'], notifier)
def _test_is_dvr_serviced(self, device_owner, expected): self.assertEqual(expected, utils.is_dvr_serviced(device_owner))
def test_check_if_compute_port_serviced_by_dvr(self): self.assertTrue(utils.is_dvr_serviced('compute:None'))
def get_dvr_routers_to_remove(self, context, deleted_port, get_related_hosts_info=True): """Returns info about which routers should be removed In case dvr serviceable port was deleted we need to check if any dvr routers should be removed from l3 agent on port's host """ if not n_utils.is_dvr_serviced(deleted_port['device_owner']): return [] admin_context = context.elevated() port_host = deleted_port[portbindings.HOST_ID] subnet_ids = [ip['subnet_id'] for ip in deleted_port['fixed_ips']] router_ids = self.get_dvr_routers_by_subnet_ids(admin_context, subnet_ids) if not router_ids: LOG.debug('No DVR routers for this DVR port %(port)s ' 'on host %(host)s', {'port': deleted_port['id'], 'host': port_host}) return [] agent = self._get_agent_by_type_and_host( context, n_const.AGENT_TYPE_L3, port_host) removed_router_info = [] # NOTE(Swami): If host has any serviceable ports, # we should not remove the router namespace of the # port as well as the connected routers namespace. # After all serviceable ports in the host for the # connected routers are deleted, then we can remove # the router namespace. host_has_serviceable_port = False for router_id in router_ids: if rb_obj.RouterL3AgentBinding.objects_exist(context, router_id=router_id, l3_agent_id=agent.id): # not removing from the agent hosting SNAT for the router continue if self._check_for_rtr_serviceable_ports( admin_context, router_id, port_host): # once we found a serviceable port there is no need to # check further host_has_serviceable_port = True break self._unbind_dvr_port_before_delete(context, router_id, port_host) info = {'router_id': router_id, 'host': port_host, 'agent_id': str(agent.id)} removed_router_info.append(info) # Now collect the connected router info as well to remove # it from the agent, only if there is not a serviceable port. if not host_has_serviceable_port: related_router_ids = set() for router_id in router_ids: connected_dvr_router_ids = set( self._get_other_dvr_router_ids_connected_router( context, router_id)) related_router_ids |= connected_dvr_router_ids related_router_ids = [r_id for r_id in related_router_ids if r_id not in list(router_ids)] for router_id in related_router_ids: if self._check_for_rtr_serviceable_ports( admin_context, router_id, port_host): # once we found a serviceable port there is no need to # check further host_has_serviceable_port = True break self._unbind_dvr_port_before_delete(context, router_id, port_host) info = {'router_id': router_id, 'host': port_host, 'agent_id': str(agent.id)} removed_router_info.append(info) LOG.debug("Router info to be deleted: %s", removed_router_info) return removed_router_info
def _should_update_arp_entry_for_dvr_service_port(self, port_dict): # Check this is a valid VM or service port return (n_utils.is_dvr_serviced(port_dict['device_owner']) and port_dict['fixed_ips'])
def test_check_if_port_not_serviced_by_dvr(self): self.assertFalse( utils.is_dvr_serviced(constants.DEVICE_OWNER_ROUTER_INTF))
def test_check_if_dhcp_port_serviced_by_dvr(self): self.assertTrue(utils.is_dvr_serviced(constants.DEVICE_OWNER_DHCP))
def _get_dvr_service_port_hostid(self, context, port_id, port=None): """Returns the portbinding host_id for dvr service port.""" port_db = port or self._core_plugin.get_port(context, port_id) device_owner = port_db['device_owner'] if port_db else "" if n_utils.is_dvr_serviced(device_owner): return port_db[portbindings.HOST_ID]
def test_check_if_lbaas_vip_port_serviced_by_dvr(self): self.assertTrue( utils.is_dvr_serviced(constants.DEVICE_OWNER_LOADBALANCER))
def _notify_l3_agent_port_update(resource, event, trigger, **kwargs): new_port = kwargs.get('port') original_port = kwargs.get('original_port') if new_port and original_port: original_device_owner = original_port.get('device_owner', '') new_device_owner = new_port.get('device_owner', '') is_new_device_dvr_serviced = n_utils.is_dvr_serviced(new_device_owner) l3plugin = directory.get_plugin(n_const.L3) context = kwargs['context'] is_port_no_longer_serviced = ( n_utils.is_dvr_serviced(original_device_owner) and not n_utils.is_dvr_serviced(new_device_owner)) is_port_moved = ( original_port[portbindings.HOST_ID] and original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID]) if is_port_no_longer_serviced or is_port_moved: removed_routers = l3plugin.get_dvr_routers_to_remove( context, original_port) if removed_routers: removed_router_args = { 'context': context, 'port': original_port, 'removed_routers': removed_routers, } _notify_port_delete( event, resource, trigger, **removed_router_args) fip = l3plugin._get_floatingip_on_port(context, port_id=original_port['id']) if fip and not (removed_routers and fip['router_id'] in removed_routers): l3plugin.l3_rpc_notifier.routers_updated_on_host( context, [fip['router_id']], original_port[portbindings.HOST_ID]) if not is_new_device_dvr_serviced: return is_new_port_binding_changed = ( new_port[portbindings.HOST_ID] and (original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID])) dest_host = None new_port_profile = new_port.get(portbindings.PROFILE) if new_port_profile: dest_host = new_port_profile.get('migrating_to') # This check is required to prevent an arp update # of the allowed_address_pair port. if new_port_profile.get('original_owner'): return # If dest_host is set, then the port profile has changed # and this port is in migration. The call below will # pre-create the router on the new host if ((is_new_port_binding_changed or dest_host) and is_new_device_dvr_serviced): l3plugin.dvr_handle_new_service_port(context, new_port, dest_host=dest_host) l3plugin.update_arp_entry_for_dvr_service_port( context, new_port) return # Check for allowed_address_pairs and port state new_port_host = new_port.get(portbindings.HOST_ID) allowed_address_pairs_list = new_port.get('allowed_address_pairs') if allowed_address_pairs_list and new_port_host: new_port_state = new_port.get('admin_state_up') original_port_state = original_port.get('admin_state_up') if new_port_state and not original_port_state: # Case were we activate the port from inactive state. for address_pair in allowed_address_pairs_list: _dvr_handle_unbound_allowed_addr_pair_add( l3plugin, context, new_port, address_pair) return elif original_port_state and not new_port_state: # Case were we deactivate the port from active state. for address_pair in allowed_address_pairs_list: _dvr_handle_unbound_allowed_addr_pair_del( l3plugin, context, original_port, address_pair) return elif new_port_state and original_port_state: # Case were the same port has additional address_pairs # added. for address_pair in allowed_address_pairs_list: _dvr_handle_unbound_allowed_addr_pair_add( l3plugin, context, new_port, address_pair) return is_fixed_ips_changed = ( 'fixed_ips' in new_port and 'fixed_ips' in original_port and new_port['fixed_ips'] != original_port['fixed_ips']) if kwargs.get('mac_address_updated') or is_fixed_ips_changed: l3plugin.update_arp_entry_for_dvr_service_port( context, new_port)
def test_check_if_port_not_serviced_by_dvr(self): self.assertFalse(utils.is_dvr_serviced( constants.DEVICE_OWNER_ROUTER_INTF))
def _notify_l3_agent_port_update(resource, event, trigger, **kwargs): new_port = kwargs.get('port') original_port = kwargs.get('original_port') if new_port and original_port: original_device_owner = original_port.get('device_owner', '') new_device_owner = new_port.get('device_owner', '') is_new_device_dvr_serviced = n_utils.is_dvr_serviced(new_device_owner) l3plugin = manager.NeutronManager.get_service_plugins().get( service_constants.L3_ROUTER_NAT) context = kwargs['context'] is_port_no_longer_serviced = ( n_utils.is_dvr_serviced(original_device_owner) and not n_utils.is_dvr_serviced(new_device_owner)) is_port_moved = (original_port[portbindings.HOST_ID] and original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID]) if is_port_no_longer_serviced or is_port_moved: removed_routers = l3plugin.get_dvr_routers_to_remove( context, original_port) if removed_routers: removed_router_args = { 'context': context, 'port': original_port, 'removed_routers': removed_routers, } _notify_port_delete(event, resource, trigger, **removed_router_args) fip = l3plugin._get_floatingip_on_port(context, port_id=original_port['id']) if fip and not (removed_routers and fip['router_id'] in removed_routers): l3plugin.l3_rpc_notifier.routers_updated_on_host( context, [fip['router_id']], original_port[portbindings.HOST_ID]) if not is_new_device_dvr_serviced: return is_new_port_binding_changed = (new_port[portbindings.HOST_ID] and (original_port[portbindings.HOST_ID] != new_port[portbindings.HOST_ID])) dest_host = None new_port_profile = new_port.get(portbindings.PROFILE) if new_port_profile: dest_host = new_port_profile.get('migrating_to') # This check is required to prevent an arp update # of the allowed_address_pair port. if new_port_profile.get('original_owner'): return # If dest_host is set, then the port profile has changed # and this port is in migration. The call below will # pre-create the router on the new host if ((is_new_port_binding_changed or dest_host) and is_new_device_dvr_serviced): l3plugin.dvr_handle_new_service_port(context, new_port, dest_host=dest_host) l3plugin.update_arp_entry_for_dvr_service_port(context, new_port) return # Check for allowed_address_pairs and port state new_port_host = new_port.get(portbindings.HOST_ID) allowed_address_pairs_list = new_port.get('allowed_address_pairs') if allowed_address_pairs_list and new_port_host: new_port_state = new_port.get('admin_state_up') original_port_state = original_port.get('admin_state_up') if new_port_state and not original_port_state: # Case were we activate the port from inactive state. for address_pair in allowed_address_pairs_list: _dvr_handle_unbound_allowed_addr_pair_add( l3plugin, context, new_port, address_pair) return elif original_port_state and not new_port_state: # Case were we deactivate the port from active state. for address_pair in allowed_address_pairs_list: _dvr_handle_unbound_allowed_addr_pair_del( l3plugin, context, original_port, address_pair) return elif new_port_state and original_port_state: # Case were the same port has additional address_pairs # added. for address_pair in allowed_address_pairs_list: _dvr_handle_unbound_allowed_addr_pair_add( l3plugin, context, new_port, address_pair) return is_fixed_ips_changed = ( 'fixed_ips' in new_port and 'fixed_ips' in original_port and new_port['fixed_ips'] != original_port['fixed_ips']) if kwargs.get('mac_address_updated') or is_fixed_ips_changed: l3plugin.update_arp_entry_for_dvr_service_port(context, new_port)