From 07294ffd83191093fc1086ff9d1949666be57971 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Fri, 29 Dec 2023 13:29:02 +0100 Subject: vyos.template: T5869: first_host_address() does not honor RFC4291 section 2.6.1 The subnet router anycast address is predefined. Its format is as follows: | n bits | 128-n bits | +------------------------------------------------+----------------+ | subnet prefix | 00000000000000 | +------------------------------------------------+----------------+ The "subnet prefix" in an anycast address is the prefix that identifies a specific link. This anycast address is syntactically the same as a unicast address for an interface on the link with the interface identifier set to zero. Packets sent to the Subnet-Router anycast address will be delivered to one router on the subnet. All routers are required to support the Subnet-Router anycast addresses for the subnets to which they have interfaces. The Subnet-Router anycast address is intended to be used for applications where a node needs to communicate with any one of the set of routers. Our code as of now returns the subnet router anycast address as the first_host_address(). (cherry picked from commit cc4ce81ece57faca8ce111b8f3748389ecb40202) --- python/vyos/template.py | 11 +++-------- src/tests/test_template.py | 13 ++++++++----- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/python/vyos/template.py b/python/vyos/template.py index 216f967a7..119ea54d6 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -316,20 +316,15 @@ def is_ipv6(text): except: return False @register_filter('first_host_address') -def first_host_address(text): +def first_host_address(prefix): """ Return first usable (host) IP address from given prefix. Example: - 10.0.0.0/24 -> 10.0.0.1 - 2001:db8::/64 -> 2001:db8:: """ from ipaddress import ip_interface - from ipaddress import IPv4Network - from ipaddress import IPv6Network - - addr = ip_interface(text) - if addr.version == 4: - return str(addr.ip +1) - return str(addr.ip) + tmp = ip_interface(prefix).network + return str(tmp.network_address +1) @register_filter('last_host_address') def last_host_address(text): diff --git a/src/tests/test_template.py b/src/tests/test_template.py index 2d065f545..cff977283 100644 --- a/src/tests/test_template.py +++ b/src/tests/test_template.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-2023 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -81,9 +81,13 @@ class TestVyOSTemplate(TestCase): self.assertEqual(vyos.template.netmask_from_cidr('2001:db8:1:/64'), 'ffff:ffff:ffff:ffff::') def test_first_host_address(self): - self.assertEqual(vyos.template.first_host_address('10.0.0.0/24'), '10.0.0.1') - self.assertEqual(vyos.template.first_host_address('10.0.0.128/25'), '10.0.0.129') - self.assertEqual(vyos.template.first_host_address('2001:db8::/64'), '2001:db8::') + self.assertEqual(vyos.template.first_host_address('10.0.0.0/24'), '10.0.0.1') + self.assertEqual(vyos.template.first_host_address('10.0.0.10/24'), '10.0.0.1') + self.assertEqual(vyos.template.first_host_address('10.0.0.255/24'), '10.0.0.1') + self.assertEqual(vyos.template.first_host_address('10.0.0.128/25'), '10.0.0.129') + self.assertEqual(vyos.template.first_host_address('2001:db8::/64'), '2001:db8::1') + self.assertEqual(vyos.template.first_host_address('2001:db8::1000/64'), '2001:db8::1') + self.assertEqual(vyos.template.first_host_address('2001:db8::ffff:ffff:ffff:ffff/64'), '2001:db8::1') def test_last_host_address(self): self.assertEqual(vyos.template.last_host_address('10.0.0.0/24'), '10.0.0.254') @@ -181,4 +185,3 @@ class TestVyOSTemplate(TestCase): for group_name, group_config in data['ike_group'].items(): ciphers = vyos.template.get_esp_ike_cipher(group_config) self.assertIn(IKEv2_DEFAULT, ','.join(ciphers)) - -- cgit v1.2.3 From b0754013579f6e5db9027cc5123c99ba18a700a2 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Fri, 29 Dec 2023 13:30:43 +0100 Subject: tests: T5869: consolidate duplicated test cases We have had duplicated test cases in test_jinja_filters.py and test_template.py, They have been consolidated into test_template.py. (cherry picked from commit 80e2e80b5504d1da643a0d5c9772a1f9dee0aa99) --- src/tests/test_jinja_filters.py | 69 ----------------------------------------- src/tests/test_template.py | 31 +++++++++++------- 2 files changed, 19 insertions(+), 81 deletions(-) delete mode 100644 src/tests/test_jinja_filters.py diff --git a/src/tests/test_jinja_filters.py b/src/tests/test_jinja_filters.py deleted file mode 100644 index 8a7241fe3..000000000 --- a/src/tests/test_jinja_filters.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2020 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from unittest import TestCase - -from ipaddress import ip_network -from vyos.template import address_from_cidr -from vyos.template import netmask_from_cidr -from vyos.template import is_ipv4 -from vyos.template import is_ipv6 -from vyos.template import first_host_address -from vyos.template import last_host_address -from vyos.template import inc_ip - -class TestTeamplteHelpers(TestCase): - def setUp(self): - pass - - def test_helpers_from_cidr(self): - network_v4 = '192.0.2.0/26' - self.assertEqual(address_from_cidr(network_v4), str(ip_network(network_v4).network_address)) - self.assertEqual(netmask_from_cidr(network_v4), str(ip_network(network_v4).netmask)) - - def test_helpers_ipv4(self): - self.assertTrue(is_ipv4('192.0.2.1')) - self.assertTrue(is_ipv4('192.0.2.0/24')) - self.assertTrue(is_ipv4('192.0.2.1/32')) - self.assertTrue(is_ipv4('10.255.1.2')) - self.assertTrue(is_ipv4('10.255.1.0/24')) - self.assertTrue(is_ipv4('10.255.1.2/32')) - self.assertFalse(is_ipv4('2001:db8::')) - self.assertFalse(is_ipv4('2001:db8::1')) - self.assertFalse(is_ipv4('2001:db8::/64')) - - def test_helpers_ipv6(self): - self.assertFalse(is_ipv6('192.0.2.1')) - self.assertFalse(is_ipv6('192.0.2.0/24')) - self.assertFalse(is_ipv6('192.0.2.1/32')) - self.assertFalse(is_ipv6('10.255.1.2')) - self.assertFalse(is_ipv6('10.255.1.0/24')) - self.assertFalse(is_ipv6('10.255.1.2/32')) - self.assertTrue(is_ipv6('2001:db8::')) - self.assertTrue(is_ipv6('2001:db8::1')) - self.assertTrue(is_ipv6('2001:db8::1/64')) - self.assertTrue(is_ipv6('2001:db8::/32')) - self.assertTrue(is_ipv6('2001:db8::/64')) - - def test_helpers_first_host_address(self): - self.assertEqual(first_host_address('10.0.0.0/24'), '10.0.0.1') - self.assertEqual(first_host_address('10.0.0.128/25'), '10.0.0.129') - self.assertEqual(first_host_address('10.0.0.200/29'), '10.0.0.201') - - self.assertEqual(first_host_address('2001:db8::/64'), '2001:db8::') - self.assertEqual(first_host_address('2001:db8::/112'), '2001:db8::') - self.assertEqual(first_host_address('2001:db8::10/112'), '2001:db8::10') - self.assertEqual(first_host_address('2001:db8::100/112'), '2001:db8::100') diff --git a/src/tests/test_template.py b/src/tests/test_template.py index cff977283..aba97015e 100644 --- a/src/tests/test_template.py +++ b/src/tests/test_template.py @@ -17,6 +17,7 @@ import os import vyos.template +from ipaddress import ip_network from unittest import TestCase class TestVyOSTemplate(TestCase): @@ -67,6 +68,9 @@ class TestVyOSTemplate(TestCase): # ValueError: 2001:db8::1/48 has host bits set self.assertEqual(vyos.template.address_from_cidr('2001:db8::1/48'), '2001:db8::1') + network_v4 = '192.0.2.0/26' + self.assertEqual(vyos.template.address_from_cidr(network_v4), str(ip_network(network_v4).network_address)) + def test_netmask_from_cidr(self): self.assertEqual(vyos.template.netmask_from_cidr('192.0.2.0/24'), '255.255.255.0') self.assertEqual(vyos.template.netmask_from_cidr('192.0.2.128/25'), '255.255.255.128') @@ -80,6 +84,9 @@ class TestVyOSTemplate(TestCase): # ValueError: 2001:db8:1:/64 has host bits set self.assertEqual(vyos.template.netmask_from_cidr('2001:db8:1:/64'), 'ffff:ffff:ffff:ffff::') + network_v4 = '192.0.2.0/26' + self.assertEqual(vyos.template.netmask_from_cidr(network_v4), str(ip_network(network_v4).netmask)) + def test_first_host_address(self): self.assertEqual(vyos.template.first_host_address('10.0.0.0/24'), '10.0.0.1') self.assertEqual(vyos.template.first_host_address('10.0.0.10/24'), '10.0.0.1') @@ -90,22 +97,22 @@ class TestVyOSTemplate(TestCase): self.assertEqual(vyos.template.first_host_address('2001:db8::ffff:ffff:ffff:ffff/64'), '2001:db8::1') def test_last_host_address(self): - self.assertEqual(vyos.template.last_host_address('10.0.0.0/24'), '10.0.0.254') - self.assertEqual(vyos.template.last_host_address('10.0.0.128/25'), '10.0.0.254') - self.assertEqual(vyos.template.last_host_address('2001:db8::/64'), '2001:db8::ffff:ffff:ffff:ffff') + self.assertEqual(vyos.template.last_host_address('10.0.0.0/24'), '10.0.0.254') + self.assertEqual(vyos.template.last_host_address('10.0.0.128/25'), '10.0.0.254') + self.assertEqual(vyos.template.last_host_address('2001:db8::/64'), '2001:db8::ffff:ffff:ffff:ffff') def test_increment_ip(self): - self.assertEqual(vyos.template.inc_ip('10.0.0.0/24', '2'), '10.0.0.2') - self.assertEqual(vyos.template.inc_ip('10.0.0.0', '2'), '10.0.0.2') - self.assertEqual(vyos.template.inc_ip('10.0.0.0', '10'), '10.0.0.10') - self.assertEqual(vyos.template.inc_ip('2001:db8::/64', '2'), '2001:db8::2') - self.assertEqual(vyos.template.inc_ip('2001:db8::', '10'), '2001:db8::a') + self.assertEqual(vyos.template.inc_ip('10.0.0.0/24', '2'), '10.0.0.2') + self.assertEqual(vyos.template.inc_ip('10.0.0.0', '2'), '10.0.0.2') + self.assertEqual(vyos.template.inc_ip('10.0.0.0', '10'), '10.0.0.10') + self.assertEqual(vyos.template.inc_ip('2001:db8::/64', '2'), '2001:db8::2') + self.assertEqual(vyos.template.inc_ip('2001:db8::', '10'), '2001:db8::a') def test_decrement_ip(self): - self.assertEqual(vyos.template.dec_ip('10.0.0.100/24', '1'), '10.0.0.99') - self.assertEqual(vyos.template.dec_ip('10.0.0.90', '10'), '10.0.0.80') - self.assertEqual(vyos.template.dec_ip('2001:db8::b/64', '10'), '2001:db8::1') - self.assertEqual(vyos.template.dec_ip('2001:db8::f', '5'), '2001:db8::a') + self.assertEqual(vyos.template.dec_ip('10.0.0.100/24', '1'), '10.0.0.99') + self.assertEqual(vyos.template.dec_ip('10.0.0.90', '10'), '10.0.0.80') + self.assertEqual(vyos.template.dec_ip('2001:db8::b/64', '10'), '2001:db8::1') + self.assertEqual(vyos.template.dec_ip('2001:db8::f', '5'), '2001:db8::a') def test_is_network(self): self.assertFalse(vyos.template.is_ip_network('192.0.2.0')) -- cgit v1.2.3