From f7207d49184f790378325411c6d7304e01db4f01 Mon Sep 17 00:00:00 2001 From: Hunt Xu Date: Tue, 16 Jan 2018 19:34:09 +0800 Subject: [PATCH] Fix _port_arg for security rules with icmp/ipv6-icmp aliases When a security group rule is created with icmp/ipv6-icmp alias such as protocol number 1(ICMP), 58(ICMPv6) or string icmpv6(legacy name for ipv6-icmp) as its protocol along with ICMP/ICMPv6 message type specified, _port_arg will generate a wrong str for iptables/ip6tables. Change-Id: Iae01b9a0da34797a5f061a110f06e18be9bbec5a Closes-Bug: #1743552 (cherry picked from commit 0efe1aec185365d8bd7a14ec5b812132d0f9e44d) --- neutron/agent/linux/iptables_firewall.py | 1 + .../agent/linux/test_iptables_firewall.py | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/neutron/agent/linux/iptables_firewall.py b/neutron/agent/linux/iptables_firewall.py index 2f3f0194e97..7ece5752401 100644 --- a/neutron/agent/linux/iptables_firewall.py +++ b/neutron/agent/linux/iptables_firewall.py @@ -652,6 +652,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver): if port_range_min is None: return args + protocol = n_const.IPTABLES_PROTOCOL_NAME_MAP.get(protocol, protocol) if protocol in ['icmp', 'ipv6-icmp']: protocol_type = 'icmpv6' if protocol == 'ipv6-icmp' else 'icmp' # Note(xuhanp): port_range_min/port_range_max represent diff --git a/neutron/tests/unit/agent/linux/test_iptables_firewall.py b/neutron/tests/unit/agent/linux/test_iptables_firewall.py index ad0abac3dc9..c388dccee3e 100644 --- a/neutron/tests/unit/agent/linux/test_iptables_firewall.py +++ b/neutron/tests/unit/agent/linux/test_iptables_firewall.py @@ -550,6 +550,21 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase): ingress = None self._test_prepare_port_filter(rule, ingress, egress) + def test_filter_ipv4_egress_icmp_type_code_protocol_num(self): + prefix = FAKE_PREFIX['IPv4'] + rule = {'ethertype': 'IPv4', + 'direction': 'egress', + 'protocol': '1', + 'port_range_min': 8, + 'port_range_max': 0, + 'dest_ip_prefix': prefix} + egress = mock.call.add_rule( + 'ofake_dev', + '-d %s -p icmp -m icmp --icmp-type 8/0 -j RETURN' % prefix, + comment=None) + ingress = None + self._test_prepare_port_filter(rule, ingress, egress) + def test_filter_ipv4_egress_tcp_port(self): rule = {'ethertype': 'IPv4', 'direction': 'egress', @@ -934,6 +949,36 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase): ingress = None self._test_prepare_port_filter(rule, ingress, egress) + def test_filter_ipv6_egress_icmp_type_code_protocol_num(self): + prefix = FAKE_PREFIX['IPv6'] + rule = {'ethertype': 'IPv6', + 'direction': 'egress', + 'protocol': '58', + 'port_range_min': 8, + 'port_range_max': 0, + 'dest_ip_prefix': prefix} + egress = mock.call.add_rule( + 'ofake_dev', + '-d %s -p ipv6-icmp -m icmp6 --icmpv6-type 8/0 -j RETURN' % prefix, + comment=None) + ingress = None + self._test_prepare_port_filter(rule, ingress, egress) + + def test_filter_ipv6_egress_icmp_type_code_protocol_legacy_name(self): + prefix = FAKE_PREFIX['IPv6'] + rule = {'ethertype': 'IPv6', + 'direction': 'egress', + 'protocol': 'icmpv6', + 'port_range_min': 8, + 'port_range_max': 0, + 'dest_ip_prefix': prefix} + egress = mock.call.add_rule( + 'ofake_dev', + '-d %s -p ipv6-icmp -m icmp6 --icmpv6-type 8/0 -j RETURN' % prefix, + comment=None) + ingress = None + self._test_prepare_port_filter(rule, ingress, egress) + def test_filter_ipv6_egress_tcp_port(self): rule = {'ethertype': 'IPv6', 'direction': 'egress',