From f5d38e05ac6c9c56311eb4d75ca2644d592ae535 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Mon, 4 May 2020 10:28:03 -0400 Subject: api: ip: add IP_ROUTE_LOOKUP API Add an IP_ROUTE_LOOKUP function that does either an exact match or longest prefix match in a given fib table for a given prefix returning the match if present. Add API test. Type: improvement Signed-off-by: Christian Hopps Change-ID: I67ec5a61079f4acf1349a9c646185f91f5f11806 --- test/test_ip4.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/test_ip6.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) (limited to 'test') diff --git a/test/test_ip4.py b/test/test_ip4.py index 6f8047cace9..43804c7c40a 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -214,6 +214,80 @@ class TestIPv4(VppTestCase): self.verify_capture(i, pkts) +class TestIPv4RouteLookup(VppTestCase): + """ IPv4 Route Lookup Test Case """ + routes = [] + + def route_lookup(self, prefix, exact): + return self.vapi.api(self.vapi.papi.ip_route_lookup, + { + 'table_id': 0, + 'exact': exact, + 'prefix': prefix, + }) + + @classmethod + def setUpClass(cls): + super(TestIPv4RouteLookup, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestIPv4RouteLookup, cls).tearDownClass() + + def setUp(self): + super(TestIPv4RouteLookup, self).setUp() + + drop_nh = VppRoutePath("127.0.0.1", 0xffffffff, + type=FibPathType.FIB_PATH_TYPE_DROP) + + # Add 3 routes + r = VppIpRoute(self, "1.1.0.0", 16, [drop_nh]) + r.add_vpp_config() + self.routes.append(r) + + r = VppIpRoute(self, "1.1.1.0", 24, [drop_nh]) + r.add_vpp_config() + self.routes.append(r) + + r = VppIpRoute(self, "1.1.1.1", 32, [drop_nh]) + r.add_vpp_config() + self.routes.append(r) + + def tearDown(self): + # Remove the routes we added + for r in self.routes: + r.remove_vpp_config() + + super(TestIPv4RouteLookup, self).tearDown() + + def test_exact_match(self): + # Verify we find the host route + prefix = "1.1.1.1/32" + result = self.route_lookup(prefix, True) + assert (prefix == str(result.route.prefix)) + + # Verify we find a middle prefix route + prefix = "1.1.1.0/24" + result = self.route_lookup(prefix, True) + assert (prefix == str(result.route.prefix)) + + # Verify we do not find an available LPM. + with self.vapi.assert_negative_api_retval(): + self.route_lookup("1.1.1.2/32", True) + + def test_longest_prefix_match(self): + # verify we find lpm + lpm_prefix = "1.1.1.0/24" + result = self.route_lookup("1.1.1.2/32", False) + assert (lpm_prefix == str(result.route.prefix)) + + # Verify we find the exact when not requested + result = self.route_lookup(lpm_prefix, False) + assert (lpm_prefix == str(result.route.prefix)) + + # Can't seem to delete the default route so no negative LPM test. + + class TestIPv4IfAddrRoute(VppTestCase): """ IPv4 Interface Addr Route Test Case """ diff --git a/test/test_ip6.py b/test/test_ip6.py index c92ebb5852a..87346c2964f 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -979,6 +979,80 @@ class TestIPv6(TestIPv6ND): self.assertEqual(mld.records_number, 4) +class TestIPv6RouteLookup(VppTestCase): + """ IPv6 Route Lookup Test Case """ + routes = [] + + def route_lookup(self, prefix, exact): + return self.vapi.api(self.vapi.papi.ip_route_lookup, + { + 'table_id': 0, + 'exact': exact, + 'prefix': prefix, + }) + + @classmethod + def setUpClass(cls): + super(TestIPv6RouteLookup, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestIPv6RouteLookup, cls).tearDownClass() + + def setUp(self): + super(TestIPv6RouteLookup, self).setUp() + + drop_nh = VppRoutePath("::1", 0xffffffff, + type=FibPathType.FIB_PATH_TYPE_DROP) + + # Add 3 routes + r = VppIpRoute(self, "2001:1111::", 32, [drop_nh]) + r.add_vpp_config() + self.routes.append(r) + + r = VppIpRoute(self, "2001:1111:2222::", 48, [drop_nh]) + r.add_vpp_config() + self.routes.append(r) + + r = VppIpRoute(self, "2001:1111:2222::1", 128, [drop_nh]) + r.add_vpp_config() + self.routes.append(r) + + def tearDown(self): + # Remove the routes we added + for r in self.routes: + r.remove_vpp_config() + + super(TestIPv6RouteLookup, self).tearDown() + + def test_exact_match(self): + # Verify we find the host route + prefix = "2001:1111:2222::1/128" + result = self.route_lookup(prefix, True) + assert (prefix == str(result.route.prefix)) + + # Verify we find a middle prefix route + prefix = "2001:1111:2222::/48" + result = self.route_lookup(prefix, True) + assert (prefix == str(result.route.prefix)) + + # Verify we do not find an available LPM. + with self.vapi.assert_negative_api_retval(): + self.route_lookup("2001::2/128", True) + + def test_longest_prefix_match(self): + # verify we find lpm + lpm_prefix = "2001:1111:2222::/48" + result = self.route_lookup("2001:1111:2222::2/128", False) + assert (lpm_prefix == str(result.route.prefix)) + + # Verify we find the exact when not requested + result = self.route_lookup(lpm_prefix, False) + assert (lpm_prefix == str(result.route.prefix)) + + # Can't seem to delete the default route so no negative LPM test. + + class TestIPv6IfAddrRoute(VppTestCase): """ IPv6 Interface Addr Route Test Case """ -- cgit 1.2.3-korg