Skip to content

Commit c683063

Browse files
authored
Merge pull request #140 from stackhpc/upstream/zed-2024-04-29
Synchronise zed with upstream
2 parents f75ef1c + a418da8 commit c683063

File tree

5 files changed

+102
-36
lines changed

5 files changed

+102
-36
lines changed

neutron/agent/linux/iptables_firewall.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,14 @@ def _protocol_name_map(self):
775775
if not self._iptables_protocol_name_map:
776776
tmp_map = constants.IPTABLES_PROTOCOL_NAME_MAP.copy()
777777
tmp_map.update(self._local_protocol_name_map())
778+
# iptables-save uses different strings for 'ipip' (protocol 4)
779+
# depending on the distro, which corresponds to the entry for
780+
# '4' in /etc/protocols. For example:
781+
# - 'ipencap' in Ubuntu
782+
# - 'ipv4' in CentOS/Fedora
783+
# For this reason, we need to map the string for 'ipip' to the
784+
# system-dependent string for '4', see bug #2054324.
785+
tmp_map[constants.PROTO_NAME_IPIP] = tmp_map['4']
778786
self._iptables_protocol_name_map = tmp_map
779787
return self._iptables_protocol_name_map
780788

neutron/objects/router.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
# License for the specific language governing permissions and limitations
1111
# under the License.
1212

13-
import itertools
14-
1513
import netaddr
1614

1715
from neutron_lib.api.definitions import availability_zone as az_def
@@ -409,20 +407,11 @@ def get_scoped_floating_ips(cls, context, router_ids):
409407

410408
# Filter out on router_ids
411409
query = query.filter(l3.FloatingIP.router_id.in_(router_ids))
412-
return cls._unique_floatingip_iterator(context, query)
413410

414-
@classmethod
415-
def _unique_floatingip_iterator(cls, context, query):
416-
"""Iterates over only one row per floating ip. Ignores others."""
417-
# Group rows by fip id. They must be sorted by same.
418-
q = query.order_by(l3.FloatingIP.id)
419-
keyfunc = lambda row: row[0]['id']
420-
group_iterator = itertools.groupby(q, keyfunc)
421-
422-
# Just hit the first row of each group
423-
for key, value in group_iterator:
424-
# pylint: disable=stop-iteration-return
425-
row = list(next(value))
411+
# Remove duplicate rows based on FIP IDs
412+
query = query.group_by(l3.FloatingIP.id)
413+
414+
for row in query:
426415
yield (cls._load_object(context, row[0]), row[1])
427416

428417
@classmethod

neutron/tests/unit/agent/linux/test_iptables_firewall.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,48 @@ def test_filter_ipv4_ingress_protocol_encap_by_num(self):
489489
egress = None
490490
self._test_prepare_port_filter(rule, ingress, egress)
491491

492+
def test_filter_ipv4_ingress_protocol_ipip(self):
493+
# We want to use what the system-dependent string here is for 'ipip',
494+
# as it could be 'ipencap' or 'ipv4' depending on the distro.
495+
# See bug #2054324.
496+
rule = {'ethertype': 'IPv4',
497+
'direction': 'ingress',
498+
'protocol': 'ipip'}
499+
expected_proto_name = self.firewall._iptables_protocol_name('ipip')
500+
ingress = mock.call.add_rule('ifake_dev',
501+
'-p %s -j RETURN' % expected_proto_name,
502+
top=False, comment=None)
503+
egress = None
504+
self._test_prepare_port_filter(rule, ingress, egress)
505+
506+
def test_filter_ipv4_ingress_protocol_4(self):
507+
# We want to use what the system-dependent string here is for '4',
508+
# as it could be 'ipencap' or 'ipv4' depending on the distro.
509+
# See bug #2054324.
510+
rule = {'ethertype': 'IPv4',
511+
'direction': 'ingress',
512+
'protocol': '4'}
513+
expected_proto_name = self.firewall._iptables_protocol_name('4')
514+
ingress = mock.call.add_rule('ifake_dev',
515+
'-p %s -j RETURN' % expected_proto_name,
516+
top=False, comment=None)
517+
egress = None
518+
self._test_prepare_port_filter(rule, ingress, egress)
519+
520+
def test_filter_ipv4_ingress_protocol_94(self):
521+
# We want to use what the system-dependent string here is for '94',
522+
# as it could be 'ipip' or something else depending on the distro.
523+
# See bug #2054324.
524+
rule = {'ethertype': 'IPv4',
525+
'direction': 'ingress',
526+
'protocol': '94'}
527+
expected_proto_name = self.firewall._iptables_protocol_name('94')
528+
ingress = mock.call.add_rule('ifake_dev',
529+
'-p %s -j RETURN' % expected_proto_name,
530+
top=False, comment=None)
531+
egress = None
532+
self._test_prepare_port_filter(rule, ingress, egress)
533+
492534
def test_filter_ipv4_ingress_protocol_999_local(self):
493535
# There is no protocol 999, so let's return a mapping
494536
# that says there is and make sure the rule is created

neutron/tests/unit/db/test_l3_db.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -252,27 +252,6 @@ def test__make_floatingip_dict_with_scope(self, make_fip_dict):
252252
'fixed_ip_address_scope': mock.sentinel.address_scope_id,
253253
'id': mock.sentinel.fip_ip}, result)
254254

255-
def test__unique_floatingip_iterator(self):
256-
context = mock.MagicMock()
257-
query = mock.MagicMock()
258-
query.order_by().__iter__.return_value = [
259-
({'id': 'id1'}, 'scope1'),
260-
({'id': 'id1'}, 'scope1'),
261-
({'id': 'id2'}, 'scope2'),
262-
({'id': 'id2'}, 'scope2'),
263-
({'id': 'id2'}, 'scope2'),
264-
({'id': 'id3'}, 'scope3')]
265-
query.reset_mock()
266-
with mock.patch.object(
267-
l3_obj.FloatingIP, '_load_object',
268-
side_effect=({'id': 'id1'}, {'id': 'id2'}, {'id': 'id3'})):
269-
result = list(
270-
l3_obj.FloatingIP._unique_floatingip_iterator(context, query))
271-
query.order_by.assert_called_once_with(l3_models.FloatingIP.id)
272-
self.assertEqual([({'id': 'id1'}, 'scope1'),
273-
({'id': 'id2'}, 'scope2'),
274-
({'id': 'id3'}, 'scope3')], result)
275-
276255
@mock.patch.object(directory, 'get_plugin')
277256
def test_prevent_l3_port_deletion_port_not_found(self, gp):
278257
# port not found doesn't prevent

neutron/tests/unit/objects/test_router.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15+
from itertools import chain
1516
from unittest import mock
1617

18+
import netaddr
19+
1720
from neutron_lib.db import api as db_api
1821
from oslo_utils import uuidutils
1922

@@ -293,6 +296,51 @@ def test_v1_2_to_v1_1_drops_qos_network_policy_id(self):
293296
self.assertNotIn('qos_network_policy_id',
294297
obj_v1_1['versioned_object.data'])
295298

299+
def test_get_scoped_floating_ips(self):
300+
def compare_results(router_ids, original_fips):
301+
self.assertCountEqual(
302+
original_fips,
303+
[
304+
fip[0].id
305+
for fip in router.FloatingIP.get_scoped_floating_ips(
306+
self.context, router_ids)
307+
]
308+
)
309+
310+
# Setup three routers, networks and external networks
311+
routers = {}
312+
for i in range(3):
313+
router_id = self._create_test_router_id(name=f'router-{i}')
314+
routers[router_id] = []
315+
net_id = self._create_test_network_id()
316+
fip_net_id = self._create_external_network_id()
317+
318+
# Create three subnets and three FIPs using the
319+
# aforementioned networks and routers
320+
for j in range(3):
321+
self._create_test_subnet_id(net_id)
322+
fip = router.FloatingIP(
323+
self.context,
324+
floating_ip_address=netaddr.IPAddress(f'10.{i}.{j}.3'),
325+
floating_network_id=fip_net_id,
326+
floating_port_id=self._create_test_port_id(
327+
network_id=fip_net_id),
328+
fixed_port_id=self._create_test_port_id(
329+
network_id=net_id),
330+
router_id=router_id,
331+
)
332+
fip.create()
333+
routers[router_id].append(fip.id)
334+
335+
# For each router we created, fetch the fips and ensure the
336+
# results match what we originally created
337+
for router_id, original_fips in routers.items():
338+
compare_results([router_id], original_fips)
339+
340+
# Now try to fetch all the fips for all the routers at once
341+
original_fips = list(chain.from_iterable(routers.values()))
342+
compare_results(routers.keys(), original_fips)
343+
296344

297345
class DvrFipGatewayPortAgentBindingTestCase(
298346
obj_test_base.BaseObjectIfaceTestCase):

0 commit comments

Comments
 (0)