Merge "Use normalized_cidr of the SG in the OVN driver"

This commit is contained in:
Zuul 2021-03-22 18:57:57 +00:00 committed by Gerrit Code Review
commit df3bb5b978
6 changed files with 38 additions and 27 deletions

View File

@ -12,19 +12,15 @@
# under the License.
#
import netaddr
from neutron_lib import constants as const
from neutron_lib import exceptions as n_exceptions
from oslo_config import cfg
from oslo_log import log as logging
from neutron._i18n import _
from neutron.common.ovn import constants as ovn_const
from neutron.common.ovn import utils
LOG = logging.getLogger(__name__)
# Convert the protocol number from integer to strings because that's
# how Neutron will pass it to us
PROTOCOL_NAME_TO_NUM_MAP = {k: str(v) for k, v in
@ -87,19 +83,11 @@ def acl_ethertype(r):
def acl_remote_ip_prefix(r, ip_version):
if not r['remote_ip_prefix']:
if not r['normalized_cidr']:
return ''
cidr = netaddr.IPNetwork(r['remote_ip_prefix'])
normalized_ip_prefix = "%s/%s" % (cidr.network, cidr.prefixlen)
if r['remote_ip_prefix'] != normalized_ip_prefix:
LOG.info("remote_ip_prefix %(remote_ip_prefix)s configured in "
"rule %(rule_id)s is not normalized. Normalized CIDR "
"%(normalized_ip_prefix)s will be used instead.",
{'remote_ip_prefix': r['remote_ip_prefix'],
'rule_id': r['id'],
'normalized_ip_prefix': normalized_ip_prefix})
src_or_dst = 'src' if r['direction'] == const.INGRESS_DIRECTION else 'dst'
return ' && %s.%s == %s' % (ip_version, src_or_dst, normalized_ip_prefix)
return ' && %s.%s == %s' % (
ip_version, src_or_dst, r['normalized_cidr'])
def _get_protocol_number(protocol):

View File

@ -48,6 +48,7 @@ from neutron_lib.api.definitions import qos_rule_type_details
from neutron_lib.api.definitions import qos_rules_alias
from neutron_lib.api.definitions import rbac_address_scope
from neutron_lib.api.definitions import router_availability_zone as raz_def
from neutron_lib.api.definitions import security_groups_normalized_cidr
from neutron_lib.api.definitions import security_groups_remote_address_group
from neutron_lib.api.definitions import segment as seg_def
from neutron_lib.api.definitions import sorting
@ -104,6 +105,7 @@ ML2_SUPPORTED_API_EXTENSIONS = [
'rbac-policies',
'standard-attr-revisions',
'security-group',
security_groups_normalized_cidr.ALIAS,
security_groups_remote_address_group.ALIAS,
'standard-attr-description',
constants.SUBNET_ALLOCATION_EXT_ALIAS,

View File

@ -22,7 +22,6 @@ import threading
import types
import uuid
import netaddr
from neutron_lib.api.definitions import portbindings
from neutron_lib.api.definitions import provider_net
from neutron_lib.api.definitions import segment as segment_def
@ -415,9 +414,6 @@ class OVNMechanismDriver(api.MechanismDriver):
sg_rules = self._plugin.get_security_group_rules(
n_context.get_admin_context(),
{'security_group_id': [sg_rule['security_group_id']]})
cidr_sg_rule = netaddr.IPNetwork(sg_rule['remote_ip_prefix'])
normalized_sg_rule_prefix = "%s/%s" % (cidr_sg_rule.network,
cidr_sg_rule.prefixlen)
def _rules_equal(rule1, rule2):
return not any(
@ -426,10 +422,7 @@ class OVNMechanismDriver(api.MechanismDriver):
for rule in sg_rules:
if not rule.get('remote_ip_prefix') or rule['id'] == sg_rule['id']:
continue
cidr_rule = netaddr.IPNetwork(rule['remote_ip_prefix'])
normalized_rule_prefix = "%s/%s" % (cidr_rule.network,
cidr_rule.prefixlen)
if normalized_sg_rule_prefix != normalized_rule_prefix:
if sg_rule.get('normalized_cidr') != rule.get('normalized_cidr'):
continue
if _rules_equal(sg_rule, rule):
return True

View File

@ -289,11 +289,13 @@ class TestACLs(base.BaseTestCase):
}).info()
ip_version = 'ip4'
remote_ip_prefix = '10.10.0.0/24'
normalized_cidr = '10.10.0.0/24'
match = ovn_acl.acl_remote_ip_prefix(sg_rule, ip_version)
self.assertEqual('', match)
sg_rule['remote_ip_prefix'] = remote_ip_prefix
sg_rule['normalized_cidr'] = normalized_cidr
match = ovn_acl.acl_remote_ip_prefix(sg_rule, ip_version)
expected_match = ' && %s.src == %s' % (ip_version, remote_ip_prefix)
self.assertEqual(expected_match, match)
@ -304,12 +306,13 @@ class TestACLs(base.BaseTestCase):
self.assertEqual(expected_match, match)
def test_acl_remote_ip_prefix_not_normalized(self):
sg_rule = fakes.FakeSecurityGroupRule.create_one_security_group_rule({
'direction': 'ingress',
'remote_ip_prefix': '10.10.10.175/26'
}).info()
normalized_ip_prefix = '10.10.10.128/26'
ip_version = 'ip4'
sg_rule = fakes.FakeSecurityGroupRule.create_one_security_group_rule({
'direction': 'ingress',
'remote_ip_prefix': '10.10.10.175/26',
'normalized_cidr': normalized_ip_prefix
}).info()
match = ovn_acl.acl_remote_ip_prefix(sg_rule, ip_version)
expected_match = ' && %s.src == %s' % (ip_version,

View File

@ -17,6 +17,7 @@ import copy
from unittest import mock
from neutron_lib.api.definitions import l3
from neutron_lib.utils import net
from oslo_utils import uuidutils
from neutron.common.ovn import constants as ovn_const
@ -561,6 +562,7 @@ class FakeSecurityGroupRule(object):
'protocol': 'tcp',
'remote_group_id': None,
'remote_ip_prefix': '0.0.0.0/0',
'normalized_cidr': '0.0.0.0/0',
'security_group_id': 'security-group-id-' + fake_uuid,
'tenant_id': 'project-id-' + fake_uuid,
}
@ -568,6 +570,13 @@ class FakeSecurityGroupRule(object):
# Overwrite default attributes.
security_group_rule_attrs.update(attrs)
if ('remote_ip_prefix' in attrs and 'normalized_cidr' not in attrs):
if attrs['remote_ip_prefix'] is None:
security_group_rule_attrs['normalized_cidr'] = None
else:
security_group_rule_attrs['normalized_cidr'] = (
net.AuthenticIPNetwork(attrs['remote_ip_prefix']))
return FakeResource(info=copy.deepcopy(security_group_rule_attrs),
loaded=True)

View File

@ -17,6 +17,7 @@ import datetime
from unittest import mock
import uuid
import netaddr
from neutron_lib.api.definitions import external_net
from neutron_lib.api.definitions import extra_dhcp_opt as edo_ext
from neutron_lib.api.definitions import portbindings
@ -281,29 +282,42 @@ class TestOVNMechanismDriver(test_plugin.Ml2PluginV2TestCase):
scenarios = [
({'id': 'rule-id', 'security_group_id': 'sec-group-uuid',
'remote_ip_prefix': '10.10.10.175/26',
'normalized_cidr': str(
netaddr.IPNetwork('10.10.10.175/26').cidr),
'protocol': 'tcp'}, False),
({'id': 'rule-id', 'security_group_id': 'sec-group-uuid',
'remote_ip_prefix': '10.10.10.175/26',
'normalized_cidr': str(
netaddr.IPNetwork('10.10.10.175/26').cidr),
'protocol': 'udp'}, False),
({'id': 'rule-id', 'security_group_id': 'sec-group-uuid',
'remote_ip_prefix': '10.10.10.175/26',
'normalized_cidr': str(
netaddr.IPNetwork('10.10.10.175/26').cidr),
'protocol': 'tcp'}, False),
({'id': 'rule-id', 'security_group_id': 'sec-group-uuid',
'remote_ip_prefix': '10.10.10.175/26',
'normalized_cidr': str(
netaddr.IPNetwork('10.10.10.175/26').cidr),
'protocol': 'tcp',
'port_range_min': '2000', 'port_range_max': '2100'}, False),
({'id': 'rule-id', 'security_group_id': 'sec-group-uuid',
'remote_ip_prefix': '192.168.0.0/24',
'normalized_cidr': str(netaddr.IPNetwork('192.168.0.0/24').cidr),
'protocol': 'tcp',
'port_range_min': '2000', 'port_range_max': '3000',
'direction': 'ingress'}, False),
({'id': 'rule-id', 'security_group_id': 'sec-group-uuid',
'remote_ip_prefix': '10.10.10.175/26',
'normalized_cidr': str(
netaddr.IPNetwork('10.10.10.175/26').cidr),
'protocol': 'tcp',
'port_range_min': '2000', 'port_range_max': '3000',
'direction': 'egress'}, False),
({'id': 'rule-id', 'security_group_id': 'sec-group-uuid',
'remote_ip_prefix': '10.10.10.175/26',
'normalized_cidr': str(
netaddr.IPNetwork('10.10.10.175/26').cidr),
'protocol': 'tcp',
'port_range_min': '2000', 'port_range_max': '3000',
'direction': 'ingress'}, True)]
@ -315,6 +329,8 @@ class TestOVNMechanismDriver(test_plugin.Ml2PluginV2TestCase):
}, {
'id': 'rule-2-id',
'remote_ip_prefix': '10.10.10.128/26',
'normalized_cidr': str(
netaddr.IPNetwork('10.10.10.128/26').cidr),
'protocol': 'tcp',
'port_range_min': '2000',
'port_range_max': '3000',