From bc2edc2e0cb776a8c53deea12c6d74b84fa47a99 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Mon, 12 Jun 2017 16:23:54 +0200 Subject: [PATCH] Allow creating ICMPV6 rules Right now, even if we specify a ::/0 (or other IPv6) CIDR in an ICMP rule, Horizon sets 'icmp' as the ip_protocol of that rule but neutron expects 'ipv6-icmp' which is the right ip_protocol for ICMPv6. This results in that rule never matching anything. This change makes Horizon set the ip_protocol to ipv6-icmp when the CIDR is an IPv6 one, and icmp when it's IPv4. Co-Authored-By: Akihiro Motoki Change-Id: I1f68e1e5a3e073e38ac258de5ed9c43f8acb04e9 Closes-Bug: #1652619 (cherry picked from commit d5dcf1be93d9bb26bda7b375e41f03dd297888bb) (cherry picked from commit 7a5ed4b688c7f69ce63ef600611947e08e14bcd0) --- .../project/security_groups/forms.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/openstack_dashboard/dashboards/project/security_groups/forms.py b/openstack_dashboard/dashboards/project/security_groups/forms.py index 4d85aa941f..8359f914d8 100644 --- a/openstack_dashboard/dashboards/project/security_groups/forms.py +++ b/openstack_dashboard/dashboards/project/security_groups/forms.py @@ -377,6 +377,35 @@ class AddRule(forms.SelfHandlingForm): else: self._apply_rule_menu(cleaned_data, rule_menu) + def _adjust_ip_protocol_of_icmp(self, data): + # Note that this needs to be called after IPv4/IPv6 is determined. + try: + ip_protocol = int(data['ip_protocol']) + except ValueError: + # string representation of IP protocol + ip_protocol = data['ip_protocol'] + is_ipv6 = data['ethertype'] == 'IPv6' + + if isinstance(ip_protocol, int): + # When IP protocol number is specified, we assume a user + # knows more detail on IP protocol number, + # so a warning message on a mismatch between IP proto number + # and IP version is displayed. + if is_ipv6 and ip_protocol == 1: + msg = _('58 (ipv6-icmp) should be specified for IPv6 ' + 'instead of 1.') + self._errors['ip_protocol'] = self.error_class([msg]) + elif not is_ipv6 and ip_protocol == 58: + msg = _('1 (icmp) should be specified for IPv4 ' + 'instead of 58.') + self._errors['ip_protocol'] = self.error_class([msg]) + else: + # ICMPv6 uses different an IP protocol name and number. + # To allow 'icmp' for both IPv4 and IPv6 in the form, + # we need to replace 'icmp' with 'ipv6-icmp' based on IP version. + if is_ipv6 and ip_protocol == 'icmp': + data['ip_protocol'] = 'ipv6-icmp' + def clean(self): cleaned_data = super(AddRule, self).clean() @@ -411,6 +440,8 @@ class AddRule(forms.SelfHandlingForm): ip_ver = netaddr.IPNetwork(cidr).version cleaned_data['ethertype'] = 'IPv6' if ip_ver == 6 else 'IPv4' + self._adjust_ip_protocol_of_icmp(cleaned_data) + return cleaned_data def handle(self, request, data):