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()))
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
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
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()))