diff options
author | Mohsin Kazmi <sykazmi@cisco.com> | 2024-04-19 09:10:46 +0000 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2024-06-03 12:22:10 +0000 |
commit | 5f694322a925200d698db1025e721842e80d4b38 (patch) | |
tree | ccaca75a2ec3df8c7da47d58a7bacb4b4a0163c3 | |
parent | 05b0307962519bcc61853f3810efddf90cab9217 (diff) |
fib: set the value of the sw_if_index for DROP route
Type: fix
fib_api_path_decode() is utilized by the IP route API call
to translate the path from the API to the fib_route_path_t
structure. The ip_route_add_del_handler_t function initializes
the fib_route_path_t structure to zeros, consequently setting
the sw_if_index value to 0, which is a valid value in VPP.
Typically, the default VRF (Virtual Routing and Forwarding)
has a local interface at index 0, leading to normal functionality.
However, a custom VRF table without any interface will result
in a crash.
The issue arises because the DROP route in fib_api_path_decode()
does not override the sw_if_index value with the one provided
in vl_api_fib_path_t. Subsequently, when this sw_if_index is
attempted to be resolved in the VRF table where the interface
does not exist, it leads to a crash.
This patch addresses the problem by setting the sw_if_index of
fib_route_path_t to the sw_if_index value of the API path.
To reproduce the issue, please remove the fix and run the following command:
make test-debug TEST=test_ip4.TestIPv4RouteLookup.test_exact_match
Change-Id: I5d72e91e5c701e749a92873941bee7b7b5eabd41
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
-rw-r--r-- | src/vnet/fib/fib_api.c | 1 | ||||
-rw-r--r-- | test/test_ip4.py | 47 |
2 files changed, 46 insertions, 2 deletions
diff --git a/src/vnet/fib/fib_api.c b/src/vnet/fib/fib_api.c index 07d6699d87a..1b1c0d113c0 100644 --- a/src/vnet/fib/fib_api.c +++ b/src/vnet/fib/fib_api.c @@ -190,6 +190,7 @@ fib_api_path_decode (vl_api_fib_path_t *in, break; case FIB_API_PATH_TYPE_DROP: out->frp_flags |= FIB_ROUTE_PATH_DROP; + out->frp_sw_if_index = ntohl(in->sw_if_index); break; case FIB_API_PATH_TYPE_LOCAL: out->frp_flags |= FIB_ROUTE_PATH_LOCAL; diff --git a/test/test_ip4.py b/test/test_ip4.py index 926ca77a5f8..a183b0ca0ba 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -244,12 +244,13 @@ class TestIPv4RouteLookup(VppTestCase): """IPv4 Route Lookup Test Case""" routes = [] + tables = [] - def route_lookup(self, prefix, exact): + def route_lookup(self, prefix, exact, table_id=0): return self.vapi.api( self.vapi.papi.ip_route_lookup, { - "table_id": 0, + "table_id": table_id, "exact": exact, "prefix": prefix, }, @@ -283,11 +284,30 @@ class TestIPv4RouteLookup(VppTestCase): r.add_vpp_config() self.routes.append(r) + custom_vrf = VppIpTable(self, 200) + custom_vrf.add_vpp_config() + self.tables.append(custom_vrf) + + r = VppIpRoute(self, "2.2.0.0", 16, [drop_nh], 200) + r.add_vpp_config() + self.routes.append(r) + + r = VppIpRoute(self, "2.2.2.0", 24, [drop_nh], 200) + r.add_vpp_config() + self.routes.append(r) + + r = VppIpRoute(self, "2.2.2.2", 32, [drop_nh], 200) + 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() + for vrf in self.tables: + vrf.remove_vpp_config() + super(TestIPv4RouteLookup, self).tearDown() def test_exact_match(self): @@ -305,6 +325,20 @@ class TestIPv4RouteLookup(VppTestCase): with self.vapi.assert_negative_api_retval(): self.route_lookup("1.1.1.2/32", True) + # Verify we find the host route + prefix = "2.2.2.2/32" + result = self.route_lookup(prefix, True, 200) + assert prefix == str(result.route.prefix) + + # Verify we find a middle prefix route + prefix = "2.2.2.0/24" + result = self.route_lookup(prefix, True, 200) + assert prefix == str(result.route.prefix) + + # Verify we do not find an available LPM. + with self.vapi.assert_negative_api_retval(): + self.route_lookup("2.2.2.1/32", True, 200) + def test_longest_prefix_match(self): # verify we find lpm lpm_prefix = "1.1.1.0/24" @@ -315,6 +349,15 @@ class TestIPv4RouteLookup(VppTestCase): result = self.route_lookup(lpm_prefix, False) assert lpm_prefix == str(result.route.prefix) + # verify we find lpm + lpm_prefix = "2.2.2.0/24" + result = self.route_lookup("2.2.2.1/32", False, 200) + assert lpm_prefix == str(result.route.prefix) + + # Verify we find the exact when not requested + result = self.route_lookup(lpm_prefix, False, 200) + assert lpm_prefix == str(result.route.prefix) + # Can't seem to delete the default route so no negative LPM test. |