From 6c92f5babdc3c52cf343509fc9cf9d8a9a3df390 Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Wed, 7 Aug 2019 11:46:30 -0500 Subject: ip: allow addrs from the same prefix on intf Type: feature Adding a prefix to an interface was not permitted if it overlapped with another prefix on an interface which used the same FIB. Loosen the restriction. Allow 2 or more addresses from the same prefix on a single interface. Reference count the prefix to figure out when a glean/connected route for the prefix needs to be added or removed. Added unit tests to check that the route is only removed when all addresses in the prefix are removed from the interface. Change-Id: I1a962ecb5e1ee65fc6d41f98a4cc097a51a55321 Signed-off-by: Matthew Smith --- test/test_ip4.py | 65 +++++++++++++++++++++++++++++++++++++++++----- test/test_ip6.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 136 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/test_ip4.py b/test/test_ip4.py index a6920f8dba5..0923771200e 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -15,7 +15,9 @@ from framework import VppTestCase, VppTestRunner from util import ppp from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpMRoute, \ VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \ - VppMplsTable, VppIpTable, FibPathType, find_route + VppMplsTable, VppIpTable, FibPathType, find_route, \ + VppIpInterfaceAddress +from vpp_ip import VppIpAddress from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint from vpp_papi import VppEnum @@ -210,19 +212,19 @@ class TestIPv4(VppTestCase): self.verify_capture(i, pkts) -class TestIPV4IfAddrRoute(VppTestCase): +class TestIPv4IfAddrRoute(VppTestCase): """ IPv4 Interface Addr Route Test Case """ @classmethod def setUpClass(cls): - super(TestIPV4IfAddrRoute, cls).setUpClass() + super(TestIPv4IfAddrRoute, cls).setUpClass() @classmethod def tearDownClass(cls): - super(TestIPV4IfAddrRoute, cls).tearDownClass() + super(TestIPv4IfAddrRoute, cls).tearDownClass() def setUp(self): - super(TestIPV4IfAddrRoute, self).setUp() + super(TestIPv4IfAddrRoute, self).setUp() # create 1 pg interface self.create_pg_interfaces(range(1)) @@ -233,11 +235,62 @@ class TestIPV4IfAddrRoute(VppTestCase): i.resolve_arp() def tearDown(self): - super(TestIPV4IfAddrRoute, self).tearDown() + super(TestIPv4IfAddrRoute, self).tearDown() for i in self.pg_interfaces: i.unconfig_ip4() i.admin_down() + def test_ipv4_ifaddrs_same_prefix(self): + """ IPv4 Interface Addresses Same Prefix test + + Test scenario: + + - Verify no route in FIB for prefix 10.10.10.0/24 + - Configure IPv4 address 10.10.10.10/24 on an interface + - Verify route in FIB for prefix 10.10.10.0/24 + - Configure IPv4 address 10.10.10.20/24 on an interface + - Delete 10.10.10.10/24 from interface + - Verify route in FIB for prefix 10.10.10.0/24 + - Delete 10.10.10.20/24 from interface + - Verify no route in FIB for prefix 10.10.10.0/24 + """ + + # create two addresses, verify route not present + if_addr1 = VppIpInterfaceAddress(self, self.pg0, + VppIpAddress("10.10.10.10"), 24) + if_addr2 = VppIpInterfaceAddress(self, self.pg0, + VppIpAddress("10.10.10.20"), 24) + self.assertFalse(if_addr1.query_vpp_config()) # 10.10.10.0/24 + self.assertFalse(find_route(self, "10.10.10.10", 32)) + self.assertFalse(find_route(self, "10.10.10.20", 32)) + self.assertFalse(find_route(self, "10.10.10.255", 32)) + self.assertFalse(find_route(self, "10.10.10.0", 32)) + + # configure first address, verify route present + if_addr1.add_vpp_config() + self.assertTrue(if_addr1.query_vpp_config()) # 10.10.10.0/24 + self.assertTrue(find_route(self, "10.10.10.10", 32)) + self.assertFalse(find_route(self, "10.10.10.20", 32)) + self.assertTrue(find_route(self, "10.10.10.255", 32)) + self.assertTrue(find_route(self, "10.10.10.0", 32)) + + # configure second address, delete first, verify route not removed + if_addr2.add_vpp_config() + if_addr1.remove_vpp_config() + self.assertTrue(if_addr1.query_vpp_config()) # 10.10.10.0/24 + self.assertFalse(find_route(self, "10.10.10.10", 32)) + self.assertTrue(find_route(self, "10.10.10.20", 32)) + self.assertTrue(find_route(self, "10.10.10.255", 32)) + self.assertTrue(find_route(self, "10.10.10.0", 32)) + + # delete second address, verify route removed + if_addr2.remove_vpp_config() + self.assertFalse(if_addr1.query_vpp_config()) # 10.10.10.0/24 + self.assertFalse(find_route(self, "10.10.10.10", 32)) + self.assertFalse(find_route(self, "10.10.10.20", 32)) + self.assertFalse(find_route(self, "10.10.10.255", 32)) + self.assertFalse(find_route(self, "10.10.10.0", 32)) + def test_ipv4_ifaddr_route(self): """ IPv4 Interface Address Route test diff --git a/test/test_ip6.py b/test/test_ip6.py index f8295513516..f2c4c00424e 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -20,10 +20,11 @@ from six import moves from framework import VppTestCase, VppTestRunner from util import ppp, ip6_normalize, mk_ll_addr -from vpp_ip import DpoProto +from vpp_ip import DpoProto, VppIpAddress from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \ VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \ - VppMplsRoute, VppMplsTable, VppIpTable, FibPathType + VppMplsRoute, VppMplsTable, VppIpTable, FibPathType, \ + VppIpInterfaceAddress from vpp_neighbor import find_nbr, VppNeighbor from vpp_pg_interface import is_ipv6_misc from vpp_sub_interface import VppSubInterface, VppDot1QSubint @@ -935,6 +936,80 @@ class TestIPv6(TestIPv6ND): self.pg0.ip6_ra_config(no=1, suppress=1, send_unicast=0) +class TestIPv6IfAddrRoute(VppTestCase): + """ IPv6 Interface Addr Route Test Case """ + + @classmethod + def setUpClass(cls): + super(TestIPv6IfAddrRoute, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestIPv6IfAddrRoute, cls).tearDownClass() + + def setUp(self): + super(TestIPv6IfAddrRoute, self).setUp() + + # create 1 pg interface + self.create_pg_interfaces(range(1)) + + for i in self.pg_interfaces: + i.admin_up() + i.config_ip6() + i.resolve_ndp() + + def tearDown(self): + super(TestIPv6IfAddrRoute, self).tearDown() + for i in self.pg_interfaces: + i.unconfig_ip6() + i.admin_down() + + def test_ipv6_ifaddrs_same_prefix(self): + """ IPv6 Interface Addresses Same Prefix test + + Test scenario: + + - Verify no route in FIB for prefix 2001:10::/64 + - Configure IPv4 address 2001:10::10/64 on an interface + - Verify route in FIB for prefix 2001:10::/64 + - Configure IPv4 address 2001:10::20/64 on an interface + - Delete 2001:10::10/64 from interface + - Verify route in FIB for prefix 2001:10::/64 + - Delete 2001:10::20/64 from interface + - Verify no route in FIB for prefix 2001:10::/64 + """ + + addr1 = "2001:10::10" + addr2 = "2001:10::20" + + if_addr1 = VppIpInterfaceAddress(self, self.pg0, + VppIpAddress(addr1), 64) + if_addr2 = VppIpInterfaceAddress(self, self.pg0, + VppIpAddress(addr2), 64) + self.assertFalse(if_addr1.query_vpp_config()) # 2001:10::/64 + self.assertFalse(find_route(self, addr1, 128)) + self.assertFalse(find_route(self, addr2, 128)) + + # configure first address, verify route present + if_addr1.add_vpp_config() + self.assertTrue(if_addr1.query_vpp_config()) # 2001:10::/64 + self.assertTrue(find_route(self, addr1, 128)) + self.assertFalse(find_route(self, addr2, 128)) + + # configure second address, delete first, verify route not removed + if_addr2.add_vpp_config() + if_addr1.remove_vpp_config() + self.assertTrue(if_addr1.query_vpp_config()) # 2001:10::/64 + self.assertFalse(find_route(self, addr1, 128)) + self.assertTrue(find_route(self, addr2, 128)) + + # delete second address, verify route removed + if_addr2.remove_vpp_config() + self.assertFalse(if_addr1.query_vpp_config()) # 2001:10::/64 + self.assertFalse(find_route(self, addr1, 128)) + self.assertFalse(find_route(self, addr2, 128)) + + class TestICMPv6Echo(VppTestCase): """ ICMPv6 Echo Test Case """ -- cgit 1.2.3-korg