def _get_port_infos(self, port, segment, agent_host): if not agent_host: return session = db_api.get_session() agent = l2pop_db.get_agent_by_host(session, agent_host) if not agent: return agent_ip = l2pop_db.get_agent_ip(agent) if not agent_ip: LOG.warning(_LW("Unable to retrieve the agent ip, check the agent " "configuration.")) return if not segment: LOG.warning(_LW("Port %(port)s updated by agent %(agent)s " "isn't bound to any segment"), {'port': port['id'], 'agent': agent}) return network_types = l2pop_db.get_agent_l2pop_network_types(agent) if network_types is None: network_types = l2pop_db.get_agent_tunnel_types(agent) if segment['network_type'] not in network_types: return fdb_entries = [l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip['ip_address']) for ip in port['fixed_ips']] return agent_ip, fdb_entries
def _get_agent_fdb(self, segment, port, agent_host): if not agent_host: return network_id = port['network_id'] session = db_api.get_session() agent_active_ports = l2pop_db.get_agent_network_active_port_count( session, agent_host, network_id) agent = l2pop_db.get_agent_by_host(db_api.get_session(), agent_host) if not self._validate_segment(segment, port['id'], agent): return agent_ip = l2pop_db.get_agent_ip(agent) other_fdb_entries = self._get_fdb_entries_template( segment, agent_ip, port['network_id']) if agent_active_ports == 0: # Agent is removing its last activated port in this network, # other agents needs to be notified to delete their flooding entry. other_fdb_entries[network_id]['ports'][agent_ip].append( const.FLOODING_ENTRY) # Notify other agents to remove fdb rules for current port if port['device_owner'] != const.DEVICE_OWNER_DVR_INTERFACE: fdb_entries = self._get_port_fdb_entries(port) other_fdb_entries[network_id]['ports'][agent_ip] += fdb_entries return other_fdb_entries
def _get_agent_fdb(self, context, segment, port, agent_host): if not agent_host: return network_id = port['network_id'] agent_active_ports = l2pop_db.get_agent_network_active_port_count( context, agent_host, network_id) agent = l2pop_db.get_agent_by_host(context, agent_host) if not agent: LOG.warning("Unable to retrieve active L2 agent on host %s", agent_host) return if not self._validate_segment(segment, port['id'], agent): return agent_ip = l2pop_db.get_agent_ip(agent) other_fdb_entries = self._get_fdb_entries_template( segment, agent_ip, port['network_id']) if agent_active_ports == 0: # Agent is removing its last activated port in this network, # other agents needs to be notified to delete their flooding entry. other_fdb_entries[network_id]['ports'][agent_ip].append( const.FLOODING_ENTRY) # Notify other agents to remove fdb rules for current port if (port['device_owner'] != const.DEVICE_OWNER_DVR_INTERFACE and not l3_hamode_db.is_ha_router_port(context, port['device_owner'], port['device_id'])): fdb_entries = self._get_port_fdb_entries(port) other_fdb_entries[network_id]['ports'][agent_ip] += fdb_entries return other_fdb_entries
def _get_ha_port_agents_fdb( self, session, network_id, router_id): other_fdb_ports = {} for agent in l2pop_db.get_ha_agents_by_router_id(session, router_id): agent_active_ports = l2pop_db.get_agent_network_active_port_count( session, agent.host, network_id) if agent_active_ports == 0: ip = l2pop_db.get_agent_ip(agent) other_fdb_ports[ip] = [const.FLOODING_ENTRY] return other_fdb_ports
def update_port_up(self, context, agent_restarted=None): port = context.current agent_host = context.host port_context = context._plugin_context agent = l2pop_db.get_agent_by_host(port_context, agent_host) if not agent: LOG.warning("Unable to retrieve active L2 agent on host %s", agent_host) return network_id = port['network_id'] agent_active_ports = l2pop_db.get_agent_network_active_port_count( port_context, agent_host, network_id) agent_ip = l2pop_db.get_agent_ip(agent) segment = context.bottom_bound_segment if not self._validate_segment(segment, port['id'], agent): return other_fdb_entries = self._get_fdb_entries_template( segment, agent_ip, network_id) other_fdb_ports = other_fdb_entries[network_id]['ports'] # with high concurrency more than 1 port may be activated on an agent # at the same time (like VM port + a DVR port) so checking for 1 or 2 is_first_port = agent_active_ports in (1, 2) if agent_restarted is None: # Only for backport compatibility, will be removed. agent_restarted = self.agent_restarted(context) if is_first_port or agent_restarted: # First port(s) activated on current agent in this network, # we have to provide it with the whole list of fdb entries agent_fdb_entries = self._create_agent_fdb(port_context, agent, segment, network_id) # And notify other agents to add flooding entry other_fdb_ports[agent_ip].append(const.FLOODING_ENTRY) if agent_fdb_entries[network_id]['ports'].keys(): self.L2populationAgentNotify.add_fdb_entries( self.rpc_ctx, agent_fdb_entries, agent_host) # Notify other agents to add fdb rule for current port if (port['device_owner'] != const.DEVICE_OWNER_DVR_INTERFACE and not l3_hamode_db.is_ha_router_port( port_context, port['device_owner'], port['device_id'])): other_fdb_ports[agent_ip] += self._get_port_fdb_entries(port) self.L2populationAgentNotify.add_fdb_entries(self.rpc_ctx, other_fdb_entries)
def update_port_up(self, context): port = context.current agent_host = context.host session = db_api.get_reader_session() port_context = context._plugin_context agent = l2pop_db.get_agent_by_host(session, agent_host) if not agent: LOG.warning(_LW("Unable to retrieve active L2 agent on host %s"), agent_host) return network_id = port['network_id'] agent_active_ports = l2pop_db.get_agent_network_active_port_count( session, agent_host, network_id) agent_ip = l2pop_db.get_agent_ip(agent) segment = context.bottom_bound_segment if not self._validate_segment(segment, port['id'], agent): return other_fdb_entries = self._get_fdb_entries_template( segment, agent_ip, network_id) other_fdb_ports = other_fdb_entries[network_id]['ports'] if agent_active_ports == 1 or (l2pop_db.get_agent_uptime(agent) < cfg.CONF.l2pop.agent_boot_time): # First port activated on current agent in this network, # we have to provide it with the whole list of fdb entries agent_fdb_entries = self._create_agent_fdb(session, agent, segment, network_id) # And notify other agents to add flooding entry other_fdb_ports[agent_ip].append(const.FLOODING_ENTRY) if agent_fdb_entries[network_id]['ports'].keys(): self.L2populationAgentNotify.add_fdb_entries( self.rpc_ctx, agent_fdb_entries, agent_host) # Notify other agents to add fdb rule for current port if (port['device_owner'] != const.DEVICE_OWNER_DVR_INTERFACE and not l3_hamode_db.is_ha_router_port( port_context, port['device_owner'], port['device_id'])): other_fdb_ports[agent_ip] += self._get_port_fdb_entries(port) self.L2populationAgentNotify.add_fdb_entries(self.rpc_ctx, other_fdb_entries)
def _get_tunnels(self, tunnel_network_ports, exclude_host): agents = {} for __, agent in tunnel_network_ports: if agent.host == exclude_host: continue ip = l2pop_db.get_agent_ip(agent) if not ip: LOG.debug("Unable to retrieve the agent ip, check " "the agent %s configuration.", agent.host) continue if ip not in agents: agents[ip] = [const.FLOODING_ENTRY] return agents
def update_port_up(self, context): port = context.current agent_host = context.host session = db_api.get_session() agent = l2pop_db.get_agent_by_host(session, agent_host) if not agent: LOG.warning(_LW("Unable to retrieve active L2 agent on host %s"), agent_host) return network_id = port['network_id'] agent_active_ports = l2pop_db.get_agent_network_active_port_count( session, agent_host, network_id) agent_ip = l2pop_db.get_agent_ip(agent) segment = context.bottom_bound_segment if not self._validate_segment(segment, port['id'], agent): return other_fdb_entries = self._get_fdb_entries_template( segment, agent_ip, network_id) other_fdb_ports = other_fdb_entries[network_id]['ports'] if agent_active_ports == 1 or (l2pop_db.get_agent_uptime(agent) < cfg.CONF.l2pop.agent_boot_time): # First port activated on current agent in this network, # we have to provide it with the whole list of fdb entries agent_fdb_entries = self._create_agent_fdb(session, agent, segment, network_id) # And notify other agents to add flooding entry other_fdb_ports[agent_ip].append(const.FLOODING_ENTRY) if agent_fdb_entries[network_id]['ports'].keys(): self.L2populationAgentNotify.add_fdb_entries( self.rpc_ctx, agent_fdb_entries, agent_host) # Notify other agents to add fdb rule for current port if (port['device_owner'] != const.DEVICE_OWNER_DVR_INTERFACE and not l3_hamode_db.is_ha_router_port(port['device_owner'], port['device_id'])): other_fdb_ports[agent_ip] += self._get_port_fdb_entries(port) self.L2populationAgentNotify.add_fdb_entries(self.rpc_ctx, other_fdb_entries)
def _create_agent_fdb(self, session, agent, segment, network_id): agent_fdb_entries = {network_id: {'segment_id': segment['segmentation_id'], 'network_type': segment['network_type'], 'ports': {}}} tunnel_network_ports = ( l2pop_db.get_dvr_active_network_ports(session, network_id)) fdb_network_ports = ( l2pop_db.get_nondvr_active_network_ports(session, network_id)) ports = agent_fdb_entries[network_id]['ports'] ports.update(self._get_tunnels( fdb_network_ports + tunnel_network_ports, agent.host)) for agent_ip, fdbs in ports.items(): for binding, agent in fdb_network_ports: if l2pop_db.get_agent_ip(agent) == agent_ip: fdbs.extend(self._get_port_fdb_entries(binding.port)) return agent_fdb_entries
def _create_agent_fdb(self, context, agent, segment, network_id, source=None): exclude_host = agent.host if agent else None session = context.session agent_fdb_entries = { network_id: { 'segment_id': segment['segmentation_id'], 'network_type': segment['network_type'], 'audit': True, 'ports': {} } } physical_network = segment.get('physical_network') if physical_network: agent_fdb_entries[network_id]['physical_network'] = ( physical_network) tunnel_network_ports = (l2pop_db.get_distributed_active_network_ports( session, network_id)) fdb_network_ports = (l2pop_db.get_nondistributed_active_network_ports( session, network_id)) ports = agent_fdb_entries[network_id]['ports'] ports.update( self._get_tunnels(fdb_network_ports + tunnel_network_ports, exclude_host=exclude_host, physical_network=physical_network)) for agent_ip, fdbs in ports.items(): for binding, agent in fdb_network_ports: ip = l2pop_db.get_agent_ip( agent, physical_network=segment.get('physical_network')) if ip == agent_ip: fdbs.extend(self._get_port_fdb_entries(binding.port)) return run_fdb_extend_funcs(context, network_id, agent_fdb_entries, source=source, exclude_host=exclude_host)
def _get_tunnels(self, tunnel_network_ports, exclude_host=None, physical_network=None): agents = {} for __, agent in tunnel_network_ports: if exclude_host is not None and agent.host == exclude_host: continue ip = l2pop_db.get_agent_ip(agent, physical_network=physical_network) if not ip: LOG.debug( "Unable to retrieve the agent ip, check " "the agent %s configuration.", agent.host) continue if ip not in agents: agents[ip] = [const.FLOODING_ENTRY] return agents
def _get_agent_fdb(self, context, segment, port, agent_host, include_ha_router_ports=False): if not agent_host: return network_id = port['network_id'] session = db_api.get_reader_session() agent_active_ports = l2pop_db.get_agent_network_active_port_count( session, agent_host, network_id) agent = l2pop_db.get_agent_by_host(session, agent_host) if not agent: LOG.warning(_LW("Unable to retrieve active L2 agent on host %s"), agent_host) return if not self._validate_segment(segment, port['id'], agent): return agent_ip = l2pop_db.get_agent_ip(agent) other_fdb_entries = self._get_fdb_entries_template( segment, agent_ip, port['network_id']) if agent_active_ports == 0: # Agent is removing its last activated port in this network, # other agents needs to be notified to delete their flooding entry. other_fdb_entries[network_id]['ports'][agent_ip].append( const.FLOODING_ENTRY) # Notify other agents to remove fdb rules for current port if (port['device_owner'] != const.DEVICE_OWNER_DVR_INTERFACE and (include_ha_router_ports or not l3_hamode_db.is_ha_router_port( context, port['device_owner'], port['device_id']))): fdb_entries = self._get_port_fdb_entries(port) other_fdb_entries[network_id]['ports'][agent_ip] += fdb_entries return other_fdb_entries
def _get_port_infos(self, port, segment, agent_host): if not agent_host: return session = db_api.get_session() agent = l2pop_db.get_agent_by_host(session, agent_host) if not agent: return agent_ip = l2pop_db.get_agent_ip(agent) if not agent_ip: LOG.warning( _LW("Unable to retrieve the agent ip, check the agent " "configuration.")) return if not segment: LOG.warning( _LW("Port %(port)s updated by agent %(agent)s " "isn't bound to any segment"), { 'port': port['id'], 'agent': agent }) return network_types = l2pop_db.get_agent_l2pop_network_types(agent) if network_types is None: network_types = l2pop_db.get_agent_tunnel_types(agent) if segment['network_type'] not in network_types: return fdb_entries = [ l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip['ip_address']) for ip in port['fixed_ips'] ] return agent_ip, fdb_entries