Exemplo n.º 1
0
    def sync_address_sets(self, ctx):
        """Sync Address Sets between neutron and NB.

        @param ctx: neutron_lib.context
        @type  ctx: object of type neutron_lib.context.Context
        @var   db_ports: List of ports from neutron DB
        """
        LOG.debug('Address-Set-SYNC: started @ %s' % str(datetime.now()))

        neutron_sgs = {}
        with ctx.session.begin(subtransactions=True):
            db_sgs = self.core_plugin.get_security_groups(ctx)
            db_ports = self.core_plugin.get_ports(ctx)

        for sg in db_sgs:
            for ip_version in ['ip4', 'ip6']:
                name = utils.ovn_addrset_name(sg['id'], ip_version)
                neutron_sgs[name] = {
                    'name': name,
                    'addresses': [],
                    'external_ids': {
                        const.OVN_SG_NAME_EXT_ID_KEY: sg['name']
                    }
                }

        for port in db_ports:
            sg_ids = utils.get_lsp_security_groups(port)
            if port.get('fixed_ips') and sg_ids:
                addresses = acl_utils.acl_port_ips(port)
                for sg_id in sg_ids:
                    for ip_version in addresses:
                        name = utils.ovn_addrset_name(sg_id, ip_version)
                        neutron_sgs[name]['addresses'].extend(
                            addresses[ip_version])

        nb_sgs = self.get_address_sets()

        sgnames_to_add, sgnames_to_delete, sgs_to_update =\
            self.compute_address_set_difference(neutron_sgs, nb_sgs)

        LOG.debug('Address_Sets added %d, removed %d, updated %d',
                  len(sgnames_to_add), len(sgnames_to_delete),
                  len(sgs_to_update))

        if self.mode == SYNC_MODE_REPAIR:
            LOG.debug('Address-Set-SYNC: transaction started @ %s' %
                      str(datetime.now()))
            with self.ovn_api.transaction(check_error=True) as txn:
                for sgname in sgnames_to_add:
                    sg = neutron_sgs[sgname]
                    txn.add(self.ovn_api.create_address_set(**sg))
                for sgname, sg in sgs_to_update.items():
                    txn.add(self.ovn_api.update_address_set(**sg))
                for sgname in sgnames_to_delete:
                    txn.add(self.ovn_api.delete_address_set(name=sgname))
            LOG.debug('Address-Set-SYNC: transaction finished @ %s' %
                      str(datetime.now()))
Exemplo n.º 2
0
def add_acls(plugin, admin_context, port, sg_cache, subnet_cache, ovn):
    acl_list = []

    # Skip ACLs if security groups aren't enabled
    if not is_sg_enabled():
        return acl_list

    sec_groups = utils.get_lsp_security_groups(port)
    if not sec_groups:
        # If it is a trusted port or port security is disabled, allow all
        # traffic. So don't add any ACLs.
        if utils.is_lsp_trusted(port) or not utils.is_port_security_enabled(
                port):
            return acl_list

        # if port security is enabled, drop all traffic.
        return drop_all_ip_traffic_for_port(port)

    # Drop all IP traffic to and from the logical port by default.
    acl_list += drop_all_ip_traffic_for_port(port)

    # Add DHCP ACLs.
    port_subnet_ids = set()
    for ip in port['fixed_ips']:
        if netaddr.IPNetwork(ip['ip_address']).version != 4:
            continue
        subnet = _get_subnet_from_cache(plugin,
                                        admin_context,
                                        subnet_cache,
                                        ip['subnet_id'])
        # Ignore duplicate DHCP ACLs for the subnet.
        if subnet['id'] not in port_subnet_ids:
            acl_list += add_acl_dhcp(port, subnet, True)
            port_subnet_ids.add(subnet['id'])

    # We create an ACL entry for each rule on each security group applied
    # to this port.
    for sg_id in sec_groups:
        sg = _get_sg_from_cache(plugin,
                                admin_context,
                                sg_cache,
                                sg_id)
        for r in sg['security_group_rules']:
            acl = _add_sg_rule_acl_for_port(port, r)
            acl_list.append(acl)

    # Remove ACL log name and severity if not supported,
    if not _acl_columns_name_severity_supported(ovn):
        for acl in acl_list:
            acl.pop('name')
            acl.pop('severity')

    return acl_list
Exemplo n.º 3
0
def add_acls(plugin, admin_context, port, sg_cache, subnet_cache):
    acl_list = []

    # Skip ACLs if security groups aren't enabled
    if not is_sg_enabled():
        return acl_list

    sec_groups = utils.get_lsp_security_groups(port)
    if not sec_groups:
        return acl_list

    # Drop all IP traffic to and from the logical port by default.
    acl_list += drop_all_ip_traffic_for_port(port)

    # Add DHCP ACLs if not using OVN native DHCP.
    if not config.is_ovn_dhcp():
        port_subnet_ids = set()
        for ip in port['fixed_ips']:
            if netaddr.IPNetwork(ip['ip_address']).version != 4:
                continue
            subnet = _get_subnet_from_cache(plugin, admin_context,
                                            subnet_cache, ip['subnet_id'])
            # Ignore duplicate DHCP ACLs for the subnet.
            if subnet['id'] not in port_subnet_ids:
                acl_list += add_acl_dhcp(port, subnet)
                port_subnet_ids.add(subnet['id'])

    # We create an ACL entry for each rule on each security group applied
    # to this port.
    for sg_id in sec_groups:
        sg = _get_sg_from_cache(plugin, admin_context, sg_cache, sg_id)
        for r in sg['security_group_rules']:
            acl = _add_sg_rule_acl_for_port(port, r)
            if acl not in acl_list:
                acl_list.append(acl)

    return acl_list
Exemplo n.º 4
0
    def sync_acls(self, ctx):
        """Sync ACLs between neutron and NB.

        @param ctx: neutron_lib.context
        @type  ctx: object of type neutron_lib.context.Context
        @var   db_ports: List of ports from neutron DB
        @var   neutron_acls: neutron dictionary of port
               vs list-of-acls
        @var   nb_acls: NB dictionary of port
               vs list-of-acls
        @var   subnet_cache: cache for subnets
        @return: Nothing
        """
        LOG.debug('ACL-SYNC: started @ %s' % str(datetime.now()))

        db_ports = {}
        for port in self.core_plugin.get_ports(ctx):
            db_ports[port['id']] = port

        sg_cache = {}
        subnet_cache = {}
        neutron_acls = {}
        for port_id, port in db_ports.items():
            if utils.get_lsp_security_groups(port):
                acl_list = acl_utils.add_acls(self.core_plugin, ctx, port,
                                              sg_cache, subnet_cache)
                if port_id in neutron_acls:
                    neutron_acls[port_id].extend(acl_list)
                else:
                    neutron_acls[port_id] = acl_list

        nb_acls = self.get_acls(ctx)

        self.remove_common_acls(neutron_acls, nb_acls)

        num_acls_to_add = len(list(itertools.chain(*neutron_acls.values())))
        num_acls_to_remove = len(list(itertools.chain(*nb_acls.values())))
        if 0 != num_acls_to_add or 0 != num_acls_to_remove:
            LOG.warning(
                _LW('ACLs-to-be-added %(add)d '
                    'ACLs-to-be-removed %(remove)d'), {
                        'add': num_acls_to_add,
                        'remove': num_acls_to_remove
                    })

        if self.mode == SYNC_MODE_REPAIR:
            with self.ovn_api.transaction(check_error=True) as txn:
                for acla in list(itertools.chain(*neutron_acls.values())):
                    LOG.warning(
                        _LW('ACL found in Neutron but not in '
                            'OVN DB for port %s'), acla['lport'])
                    txn.add(self.ovn_api.add_acl(**acla))

            with self.ovn_api.transaction(check_error=True) as txn:
                for aclr in list(itertools.chain(*nb_acls.values())):
                    # Both lswitch and lport aren't needed within the ACL.
                    lswitchr = aclr.pop('lswitch').replace('neutron-', '')
                    lportr = aclr.pop('lport')
                    aclr_dict = {lportr: aclr}
                    LOG.warning(
                        _LW('ACLs found in OVN DB but not in '
                            'Neutron for port %s'), lportr)
                    txn.add(
                        self.ovn_api.update_acls([lswitchr], [lportr],
                                                 aclr_dict,
                                                 need_compare=False,
                                                 is_add_acl=False))

        LOG.debug('ACL-SYNC: finished @ %s' % str(datetime.now()))