Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
    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