From 4f89d9be7317ee5c82716306420e1d5efbcb7b31 Mon Sep 17 00:00:00 2001 From: shihanzhang Date: Tue, 14 Jul 2015 19:20:46 +0800 Subject: [PATCH] Fix handling of port-range-min 0 in secgroup RPC and agent For TCP/UDP protocol, port valid range is 0 to 65535, so for a security group rule, its valid range is also 0 to 65535. this patch makes two changes: 1. if a security group rule port_range_min is 0, l2 agent also can get port_range_min real value 0 when it gets this rule for a device via RPC. 2. For IptablesFirewallDriver, if port range is [0, xxxx], l2 agent also need add this rule to iptables. Change-Id: If93c54a31d973187889ead2c2797ffdd40a4393d Closes-bug: #1473965 --- neutron/agent/linux/iptables_firewall.py | 2 +- neutron/db/securitygroups_rpc_base.py | 4 ++-- .../agent/linux/test_iptables_firewall.py | 19 +++++++++++++++++++ .../unit/agent/test_securitygroups_rpc.py | 17 ++++++++++++----- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/neutron/agent/linux/iptables_firewall.py b/neutron/agent/linux/iptables_firewall.py index e4e1f1711..014873370 100644 --- a/neutron/agent/linux/iptables_firewall.py +++ b/neutron/agent/linux/iptables_firewall.py @@ -566,7 +566,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver): def _port_arg(self, direction, protocol, port_range_min, port_range_max): if (protocol not in ['udp', 'tcp', 'icmp', 'icmpv6'] - or not port_range_min): + or port_range_min is None): return [] if protocol in ['icmp', 'icmpv6']: diff --git a/neutron/db/securitygroups_rpc_base.py b/neutron/db/securitygroups_rpc_base.py index 63212fad9..7ae461d74 100644 --- a/neutron/db/securitygroups_rpc_base.py +++ b/neutron/db/securitygroups_rpc_base.py @@ -194,7 +194,7 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin): for key in ('protocol', 'port_range_min', 'port_range_max', 'remote_ip_prefix', 'remote_group_id'): - if rule_in_db.get(key): + if rule_in_db.get(key) is not None: if key == 'remote_ip_prefix': direction_ip_prefix = DIRECTION_IP_PREFIX[direction] rule_dict[direction_ip_prefix] = rule_in_db[key] @@ -440,7 +440,7 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin): } for key in ('protocol', 'port_range_min', 'port_range_max', 'remote_ip_prefix', 'remote_group_id'): - if rule_in_db.get(key): + if rule_in_db.get(key) is not None: if key == 'remote_ip_prefix': direction_ip_prefix = DIRECTION_IP_PREFIX[direction] rule_dict[direction_ip_prefix] = rule_in_db[key] diff --git a/neutron/tests/unit/agent/linux/test_iptables_firewall.py b/neutron/tests/unit/agent/linux/test_iptables_firewall.py index d43532df0..7b05a3fe6 100644 --- a/neutron/tests/unit/agent/linux/test_iptables_firewall.py +++ b/neutron/tests/unit/agent/linux/test_iptables_firewall.py @@ -604,6 +604,25 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase): egress = None self._test_prepare_port_filter(rule, ingress, egress) + def _test_filter_ingress_tcp_min_port_0(self, ethertype): + rule = {'ethertype': ethertype, + 'direction': 'ingress', + 'protocol': 'tcp', + 'port_range_min': 0, + 'port_range_max': 100} + ingress = mock.call.add_rule( + 'ifake_dev', + '-p tcp -m tcp -m multiport --dports 0:100 -j RETURN', + comment=None) + egress = None + self._test_prepare_port_filter(rule, ingress, egress) + + def test_filter_ingress_tcp_min_port_0_for_ipv4(self): + self._test_filter_ingress_tcp_min_port_0('IPv4') + + def test_filter_ingress_tcp_min_port_0_for_ipv6(self): + self._test_filter_ingress_tcp_min_port_0('IPv6') + def test_filter_ipv6_ingress_tcp_mport_prefix(self): prefix = FAKE_PREFIX['IPv6'] rule = {'ethertype': 'IPv6', diff --git a/neutron/tests/unit/agent/test_securitygroups_rpc.py b/neutron/tests/unit/agent/test_securitygroups_rpc.py index eb4f1ac83..030899cf7 100644 --- a/neutron/tests/unit/agent/test_securitygroups_rpc.py +++ b/neutron/tests/unit/agent/test_securitygroups_rpc.py @@ -182,7 +182,8 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase): '192.168.1.3') self.assertFalse(self.notifier.security_groups_provider_updated.called) - def test_security_group_rules_for_devices_ipv4_ingress(self): + def _test_sg_rules_for_devices_ipv4_ingress_port_range( + self, min_port, max_port): fake_prefix = FAKE_PREFIX[const.IPv4] with self.network() as n,\ self.subnet(n),\ @@ -190,8 +191,8 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase): sg1_id = sg1['security_group']['id'] rule1 = self._build_security_group_rule( sg1_id, - 'ingress', const.PROTO_NAME_TCP, '22', - '22') + 'ingress', const.PROTO_NAME_TCP, str(min_port), + str(max_port)) rule2 = self._build_security_group_rule( sg1_id, 'ingress', const.PROTO_NAME_TCP, '23', @@ -221,9 +222,9 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase): {'direction': 'ingress', 'protocol': const.PROTO_NAME_TCP, 'ethertype': const.IPv4, - 'port_range_max': 22, + 'port_range_max': max_port, 'security_group_id': sg1_id, - 'port_range_min': 22}, + 'port_range_min': min_port}, {'direction': 'ingress', 'protocol': const.PROTO_NAME_TCP, 'ethertype': const.IPv4, @@ -235,6 +236,12 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase): expected) self._delete('ports', port_id1) + def test_sg_rules_for_devices_ipv4_ingress_port_range_min_port_0(self): + self._test_sg_rules_for_devices_ipv4_ingress_port_range(0, 10) + + def test_sg_rules_for_devices_ipv4_ingress_port_range_min_port_1(self): + self._test_sg_rules_for_devices_ipv4_ingress_port_range(1, 10) + @contextlib.contextmanager def _port_with_addr_pairs_and_security_group(self): plugin_obj = manager.NeutronManager.get_plugin() -- 2.45.2