diff --git a/neutron/common/constants.py b/neutron/common/constants.py index eee92947033..410012ca360 100644 --- a/neutron/common/constants.py +++ b/neutron/common/constants.py @@ -76,6 +76,12 @@ PROTO_NAME_UDP = 'udp' PROTO_NAME_UDPLITE = 'udplite' PROTO_NAME_VRRP = 'vrrp' +# TODO(amotoki): It should be moved to neutron-lib. +# For backward-compatibility of security group rule API, +# we keep the old value for IPv6 ICMP. +# It should be clean up in the future. +PROTO_NAME_IPV6_ICMP_LEGACY = 'icmpv6' + PROTO_NUM_AH = 51 PROTO_NUM_DCCP = 33 PROTO_NUM_EGP = 8 @@ -120,6 +126,8 @@ IP_PROTOCOL_MAP = {PROTO_NAME_AH: PROTO_NUM_AH, PROTO_NAME_UDPLITE: PROTO_NUM_UDPLITE, PROTO_NAME_VRRP: PROTO_NUM_VRRP} +IP_PROTOCOL_NAME_ALIASES = {PROTO_NAME_IPV6_ICMP_LEGACY: PROTO_NAME_IPV6_ICMP} + VALID_DSCP_MARKS = [0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 46, 48, 56] diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py index 91f73d95c12..2758a9d717f 100644 --- a/neutron/db/securitygroups_db.py +++ b/neutron/db/securitygroups_db.py @@ -420,6 +420,8 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): # problems with comparing int and string in PostgreSQL. Here this # string is converted to int to give an opportunity to use it as # before. + if protocol in constants.IP_PROTOCOL_NAME_ALIASES: + protocol = constants.IP_PROTOCOL_NAME_ALIASES[protocol] return int(constants.IP_PROTOCOL_MAP.get(protocol, protocol)) def _validate_port_range(self, rule): @@ -455,6 +457,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): if rule['protocol'] in [constants.PROTO_NAME_IPV6_ENCAP, constants.PROTO_NAME_IPV6_FRAG, constants.PROTO_NAME_IPV6_ICMP, + constants.PROTO_NAME_IPV6_ICMP_LEGACY, constants.PROTO_NAME_IPV6_NONXT, constants.PROTO_NAME_IPV6_OPTS, constants.PROTO_NAME_IPV6_ROUTE]: diff --git a/neutron/extensions/securitygroup.py b/neutron/extensions/securitygroup.py index aca2f89251d..135498c6290 100644 --- a/neutron/extensions/securitygroup.py +++ b/neutron/extensions/securitygroup.py @@ -211,7 +211,12 @@ def _validate_name_not_default(data, valid_values=None): attr.validators['type:name_not_default'] = _validate_name_not_default -sg_supported_protocols = [None] + list(const.IP_PROTOCOL_MAP.keys()) +# TODO(amotoki): const.IP_PROTOCOL_MAP now comes from neutron-lib, +# so we cannot add PROTO_NAME_IPV6_ICMP_LEGACY to const.IP_PROTOCOL_MAP +# in neutron.common.constants. IP_PROTOCOL_MAP in neutron-lib should +# be updated and neutron should consume it once Mitaka backport is done. +sg_supported_protocols = ([None] + list(const.IP_PROTOCOL_MAP.keys()) + + list(const.IP_PROTOCOL_NAME_ALIASES.keys())) sg_supported_ethertypes = ['IPv4', 'IPv6'] SECURITYGROUPS = 'security_groups' SECURITYGROUPRULES = 'security_group_rules' diff --git a/neutron/tests/unit/db/test_securitygroups_db.py b/neutron/tests/unit/db/test_securitygroups_db.py index 7b104bdf900..473118c5e72 100644 --- a/neutron/tests/unit/db/test_securitygroups_db.py +++ b/neutron/tests/unit/db/test_securitygroups_db.py @@ -106,6 +106,8 @@ class SecurityGroupDbMixinTestCase(testlib_api.SqlTestCase): def test_validate_ethertype_and_protocol(self): fake_ipv4_rules = [{'protocol': constants.PROTO_NAME_IPV6_ICMP, 'ethertype': constants.IPv4}, + {'protocol': constants.PROTO_NAME_IPV6_ICMP_LEGACY, + 'ethertype': constants.IPv4}, {'protocol': constants.PROTO_NAME_IPV6_ENCAP, 'ethertype': constants.IPv4}, {'protocol': constants.PROTO_NAME_IPV6_ROUTE, diff --git a/neutron/tests/unit/extensions/test_securitygroup.py b/neutron/tests/unit/extensions/test_securitygroup.py index dbd64e9e62e..06cbdfafb96 100644 --- a/neutron/tests/unit/extensions/test_securitygroup.py +++ b/neutron/tests/unit/extensions/test_securitygroup.py @@ -834,6 +834,28 @@ class TestSecurityGroups(SecurityGroupDBTestCase): for k, v, in keys: self.assertEqual(rule['security_group_rule'][k], v) + def test_create_security_group_rule_icmpv6_legacy_protocol_name(self): + name = 'webservers' + description = 'my webservers' + with self.security_group(name, description) as sg: + security_group_id = sg['security_group']['id'] + direction = "ingress" + ethertype = const.IPv6 + remote_ip_prefix = "2001::f401:56ff:fefe:d3dc/128" + protocol = const.PROTO_NAME_IPV6_ICMP_LEGACY + keys = [('remote_ip_prefix', remote_ip_prefix), + ('security_group_id', security_group_id), + ('direction', direction), + ('ethertype', ethertype), + ('protocol', protocol)] + with self.security_group_rule(security_group_id, direction, + protocol, None, None, + remote_ip_prefix, + None, None, + ethertype) as rule: + for k, v, in keys: + self.assertEqual(rule['security_group_rule'][k], v) + def test_create_security_group_source_group_ip_and_ip_prefix(self): security_group_id = "4cd70774-cc67-4a87-9b39-7d1db38eb087" direction = "ingress"