From 76a8841f438a119ed3c6379ca7b074d033c1b5ff Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Tue, 6 Apr 2021 09:40:36 +0000 Subject: [PATCH] Fix "_get_sg_members" method Since [1], the RPC method "security_group_info_for_devices" returns not only the IP address but a list with the IP and the MAC addresses. The returned blob is like this: {sg_id: {'IPv4': [[ip1, mac1], [ip2, mac2], 'IPv6': [...]}, ...} The method "_get_sg_members" only needs the IP address, the MAC address should be discarded. NOTE: this bug was detected when testing "neutron-tempest-plugin-scenario-linuxbridge" CI job with "enable_ipset" set to False. By default, this value is set to True (it is more efficient). In order to properly test this patch, I pushed [2], creating a CI job disabling this option. To avoid overpopulating the Neutron CI, this job is not going to be added to the check gate (maybe to the periodic CI tasks). [1]https://review.opendev.org/q/I6cb2ba05fa3337be46eb01f2d9f869efa41e4db6 [2]https://review.opendev.org/c/openstack/neutron/+/783103 Change-Id: Ia5e899a4133a0952be8f607a61282e71fb0545d1 Closes-Bug: #1922127 (cherry picked from commit cca2b8de2c07e17b0917f982a006db598f6e4048) --- neutron/agent/linux/iptables_firewall.py | 3 ++- .../unit/agent/linux/test_iptables_firewall.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/neutron/agent/linux/iptables_firewall.py b/neutron/agent/linux/iptables_firewall.py index fc504b7d3eb..e496887ba9d 100644 --- a/neutron/agent/linux/iptables_firewall.py +++ b/neutron/agent/linux/iptables_firewall.py @@ -994,7 +994,8 @@ class IptablesFirewallDriver(firewall.FirewallDriver): self._clean_deleted_remote_sg_members_conntrack_entries() def _get_sg_members(self, sg_info, sg_id, ethertype): - return set(sg_info.get(sg_id, {}).get(ethertype, [])) + ip_mac_addresses = sg_info.get(sg_id, {}).get(ethertype, []) + return set([ip_mac[0] for ip_mac in ip_mac_addresses]) def filter_defer_apply_off(self): if self._defer_apply: diff --git a/neutron/tests/unit/agent/linux/test_iptables_firewall.py b/neutron/tests/unit/agent/linux/test_iptables_firewall.py index a5ce4da21d9..4af742980bd 100644 --- a/neutron/tests/unit/agent/linux/test_iptables_firewall.py +++ b/neutron/tests/unit/agent/linux/test_iptables_firewall.py @@ -2086,6 +2086,22 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase): mock.call.add_rule('sg-chain', '-j ACCEPT')] self.v4filter_inst.assert_has_calls(calls) + def test__get_sg_members(self): + sg_info = {_uuid(): {constants.IPv4: [['ip1', None]], + constants.IPv6: []}, + _uuid(): {constants.IPv4: [['ip2', None], ['ip3', None]], + constants.IPv6: [['ip4', None]]}, + } + sg_ids = list(sg_info.keys()) + self.assertEqual({'ip1'}, self.firewall._get_sg_members( + sg_info, sg_ids[0], constants.IPv4)) + self.assertEqual(set([]), self.firewall._get_sg_members( + sg_info, sg_ids[0], constants.IPv6)) + self.assertEqual({'ip2', 'ip3'}, self.firewall._get_sg_members( + sg_info, sg_ids[1], constants.IPv4)) + self.assertEqual({'ip4'}, self.firewall._get_sg_members( + sg_info, sg_ids[1], constants.IPv6)) + class IptablesFirewallEnhancedIpsetTestCase(BaseIptablesFirewallTestCase): def setUp(self):