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 <amotoki@gmail.com>
Change-Id: I1f68e1e5a3e073e38ac258de5ed9c43f8acb04e9
Closes-Bug: #1652619
(cherry picked from commit d5dcf1be93)
(cherry picked from commit 7a5ed4b688)
This commit is contained in:
Radomir Dopieralski 2017-06-12 16:23:54 +02:00 committed by Nate Johnston
parent ae1f4abd58
commit bc2edc2e0c

View File

@ -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):