From dea806da536b8f1b49af9a852441d5f772f14486 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Tue, 20 Feb 2024 11:58:01 +0500 Subject: [PATCH] fib: fix crash while adding intf-rx routes Fix crash while adding intf-rx ip4 and ip6 routes via api due invalid exporting of interface rx routes as attached. Also, add missed route path via rx-ip6 cli support. Type: fix Signed-off-by: Vladislav Grishenko Change-Id: I15711c8c0787398dd7e3baa4787019bb1f317666 --- src/vnet/bier/bier_update.c | 9 ++- src/vnet/fib/fib_types.c | 8 +++ src/vnet/fib/fib_types.h | 2 +- src/vnet/ip/lookup.c | 2 +- src/vnet/mpls/mpls.c | 8 ++- src/vnet/mpls/mpls_tunnel.c | 7 ++- test/test_ip4.py | 133 ++++++++++++++++++++++++++++++++++++++++++++ test/test_ip6.py | 133 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 297 insertions(+), 5 deletions(-) diff --git a/src/vnet/bier/bier_update.c b/src/vnet/bier/bier_update.c index 4108d09f51e..fdb7c5c0865 100644 --- a/src/vnet/bier/bier_update.c +++ b/src/vnet/bier/bier_update.c @@ -129,7 +129,14 @@ done: VLIB_CLI_COMMAND (bier_route_command) = { .path = "bier route", - .short_help = "bier route [add|del] sd set bsl bp via [next-hop-address] [next-hop-interface] [next-hop-table ] [weight ] [preference ] [udp-encap-id ] [ip4-lookup-in-table ] [ip6-lookup-in-table ] [mpls-lookup-in-table ] [resolve-via-host] [resolve-via-connected] [rx-ip4 ] [out-labels ]", + .short_help = + "bier route [add|del] sd set bsl " + "bp via [next-hop-address] [next-hop-interface] " + "[next-hop-table ] [weight ] [preference ] " + "[udp-encap-id ] [ip4-lookup-in-table ] " + "[ip6-lookup-in-table ] [mpls-lookup-in-table ] " + "[resolve-via-host] [resolve-via-connected] [rx-ip4|rx-ip6 ] " + "[out-labels ]", .function = vnet_bier_route_cmd, }; diff --git a/src/vnet/fib/fib_types.c b/src/vnet/fib/fib_types.c index 5c5fd0b9823..c4472c7122d 100644 --- a/src/vnet/fib/fib_types.c +++ b/src/vnet/fib/fib_types.c @@ -708,6 +708,13 @@ unformat_fib_route_path (unformat_input_t * input, va_list * args) rpath->frp_proto = DPO_PROTO_IP4; rpath->frp_flags = FIB_ROUTE_PATH_INTF_RX; } + else if (unformat (input, "rx-ip6 %U", + unformat_vnet_sw_interface, vnm, + &rpath->frp_sw_if_index)) + { + rpath->frp_proto = DPO_PROTO_IP6; + rpath->frp_flags = FIB_ROUTE_PATH_INTF_RX; + } else if (unformat (input, "local")) { clib_memset (&rpath->frp_addr, 0, sizeof (rpath->frp_addr)); @@ -775,6 +782,7 @@ fib_route_path_is_attached (const fib_route_path_t *rpath) * L3 game with these */ if (rpath->frp_flags & (FIB_ROUTE_PATH_DVR | + FIB_ROUTE_PATH_INTF_RX | FIB_ROUTE_PATH_UDP_ENCAP)) { return (0); diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h index 49a4b39d042..b9346c75108 100644 --- a/src/vnet/fib/fib_types.h +++ b/src/vnet/fib/fib_types.h @@ -633,7 +633,7 @@ extern int fib_route_path_is_attached (const fib_route_path_t *rpath); /** * A help string to list the FIB path options */ -#define FIB_ROUTE_PATH_HELP "[next-hop-address] [next-hop-interface] [next-hop-table ] [weight ] [preference ] [udp-encap-id ] [ip4-lookup-in-table ] [ip6-lookup-in-table ] [mpls-lookup-in-table ] [resolve-via-host] [resolve-via-connected] [rx-ip4 ] [out-labels ]" +#define FIB_ROUTE_PATH_HELP "[next-hop-address] [next-hop-interface] [next-hop-table ] [weight ] [preference ] [udp-encap-id ] [ip4-lookup-in-table ] [ip6-lookup-in-table ] [mpls-lookup-in-table ] [resolve-via-host] [resolve-via-connected] [rx-ip4|rx-ip6 ] [out-labels ]" /** * return code to control pat-hlist walk diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c index 80a35fefdfc..f86c8b61289 100644 --- a/src/vnet/ip/lookup.c +++ b/src/vnet/ip/lookup.c @@ -620,7 +620,7 @@ VLIB_CLI_COMMAND (ip_route_command, static) = { "[next-hop-table ] [weight ] [preference " "] [udp-encap ] [ip4-lookup-in-table ] " "[ip6-lookup-in-table ] [mpls-lookup-in-table ] " - "[resolve-via-host] [resolve-via-connected] [rx-ip4 " + "[resolve-via-host] [resolve-via-connected] [rx-ip4|rx-ip6 " "] [out-labels ]", .function = vnet_ip_route_cmd, .is_mp_safe = 1, diff --git a/src/vnet/mpls/mpls.c b/src/vnet/mpls/mpls.c index 0d01010feea..a04e1cf6985 100644 --- a/src/vnet/mpls/mpls.c +++ b/src/vnet/mpls/mpls.c @@ -370,7 +370,13 @@ done: VLIB_CLI_COMMAND (mpls_local_label_command, static) = { .path = "mpls local-label", .function = vnet_mpls_local_label, - .short_help = "mpls local-label [add|del] [eos|non-eos] via [next-hop-address] [next-hop-interface] [next-hop-table ] [weight ] [preference ] [udp-encap-id ] [ip4-lookup-in-table ] [ip6-lookup-in-table ] [mpls-lookup-in-table ] [resolve-via-host] [resolve-via-attached] [rx-ip4 ] [out-labels ]", + .short_help = + "mpls local-label [add|del] [eos|non-eos] via " + "[next-hop-address] [next-hop-interface] [next-hop-table ] [weight " + "] [preference ] [udp-encap-id ] " + "[ip4-lookup-in-table ] [ip6-lookup-in-table ] " + "[mpls-lookup-in-table ] [resolve-via-host] [resolve-via-attached] " + "[rx-ip4|rx-ip6 ] [out-labels ]", }; clib_error_t * diff --git a/src/vnet/mpls/mpls_tunnel.c b/src/vnet/mpls/mpls_tunnel.c index 5f7bf8c3b25..b03a4a57f68 100644 --- a/src/vnet/mpls/mpls_tunnel.c +++ b/src/vnet/mpls/mpls_tunnel.c @@ -932,7 +932,12 @@ done: VLIB_CLI_COMMAND (create_mpls_tunnel_command, static) = { .path = "mpls tunnel", .short_help = - "mpls tunnel [multicast] [l2-only] via [next-hop-address] [next-hop-interface] [next-hop-table ] [weight ] [preference ] [udp-encap-id ] [ip4-lookup-in-table ] [ip6-lookup-in-table ] [mpls-lookup-in-table ] [resolve-via-host] [resolve-via-connected] [rx-ip4 ] [out-labels ]", + "mpls tunnel [multicast] [l2-only] via [next-hop-address] " + "[next-hop-interface] [next-hop-table ] [weight ] " + "[preference ] [udp-encap-id ] [ip4-lookup-in-table " + "] [ip6-lookup-in-table ] [mpls-lookup-in-table ] " + "[resolve-via-host] [resolve-via-connected] [rx-ip4|rx-ip6 ] " + "[out-labels ]", .function = vnet_create_mpls_tunnel_command_fn, }; diff --git a/test/test_ip4.py b/test/test_ip4.py index a2a84711110..926ca77a5f8 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -3295,5 +3295,138 @@ class TestIPv4ItfRebind(VppTestCase): i.admin_down() +class TestIP4InterfaceRx(VppTestCase): + """IPv4 Interface Receive""" + + @classmethod + def setUpClass(cls): + super(TestIP4InterfaceRx, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestIP4InterfaceRx, cls).tearDownClass() + + def setUp(self): + super(TestIP4InterfaceRx, self).setUp() + + self.create_pg_interfaces(range(3)) + + table_id = 0 + + for i in self.pg_interfaces: + i.admin_up() + + if table_id != 0: + table = VppIpTable(self, table_id) + table.add_vpp_config() + + i.set_table_ip4(table_id) + i.config_ip4() + i.resolve_arp() + table_id += 1 + + def tearDown(self): + for i in self.pg_interfaces: + i.unconfig_ip4() + i.admin_down() + i.set_table_ip4(0) + + super(TestIP4InterfaceRx, self).tearDown() + + def test_interface_rx(self): + """IPv4 Interface Receive""" + + # + # add a route in the default table to receive ... + # + route_to_dst = VppIpRoute( + self, + "1.1.1.0", + 24, + [ + VppRoutePath( + "0.0.0.0", + self.pg1.sw_if_index, + type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX, + ) + ], + ) + route_to_dst.add_vpp_config() + + # + # packets to these destination are dropped, since they'll + # hit the respective default routes in table 1 + # + p_dst = ( + Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) + / IP(src="5.5.5.5", dst="1.1.1.1") + / TCP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + pkts_dst = p_dst * 10 + + self.send_and_assert_no_replies(self.pg0, pkts_dst, "IP in table 1") + + # + # add a route in the dst table to forward via pg1 + # + route_in_dst = VppIpRoute( + self, + "1.1.1.1", + 32, + [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)], + table_id=1, + ) + route_in_dst.add_vpp_config() + + self.send_and_expect(self.pg0, pkts_dst, self.pg1) + + # + # add a route in the default table to receive ... + # + route_to_dst = VppIpRoute( + self, + "1.1.1.0", + 24, + [ + VppRoutePath( + "0.0.0.0", + self.pg2.sw_if_index, + type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX, + ) + ], + table_id=1, + ) + route_to_dst.add_vpp_config() + + # + # packets to these destination are dropped, since they'll + # hit the respective default routes in table 2 + # + p_dst = ( + Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) + / IP(src="6.6.6.6", dst="1.1.1.2") + / TCP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + pkts_dst = p_dst * 10 + + self.send_and_assert_no_replies(self.pg0, pkts_dst, "IP in table 2") + + # + # add a route in the table 2 to forward via pg2 + # + route_in_dst = VppIpRoute( + self, + "1.1.1.2", + 32, + [VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index)], + table_id=2, + ) + route_in_dst.add_vpp_config() + + self.send_and_expect(self.pg0, pkts_dst, self.pg2) + + if __name__ == "__main__": unittest.main(testRunner=VppTestRunner) diff --git a/test/test_ip6.py b/test/test_ip6.py index 1e846a66c5a..87509f3f8e1 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -4087,5 +4087,138 @@ class TestIPv6Punt(VppTestCase): self.assertEqual(str(punts[2].punt.nh), "::") +class TestIP6InterfaceRx(VppTestCase): + """IPv6 Interface Receive""" + + @classmethod + def setUpClass(cls): + super(TestIP6InterfaceRx, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestIP6InterfaceRx, cls).tearDownClass() + + def setUp(self): + super(TestIP6InterfaceRx, self).setUp() + + self.create_pg_interfaces(range(3)) + + table_id = 0 + + for i in self.pg_interfaces: + i.admin_up() + + if table_id != 0: + table = VppIpTable(self, table_id, is_ip6=1) + table.add_vpp_config() + + i.set_table_ip6(table_id) + i.config_ip6() + i.resolve_ndp() + table_id += 1 + + def tearDown(self): + for i in self.pg_interfaces: + i.unconfig_ip6() + i.admin_down() + i.set_table_ip6(0) + + super(TestIP6InterfaceRx, self).tearDown() + + def test_interface_rx(self): + """IPv6 Interface Receive""" + + # + # add a route in the default table to receive ... + # + route_to_dst = VppIpRoute( + self, + "1::", + 122, + [ + VppRoutePath( + "::", + self.pg1.sw_if_index, + type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX, + ) + ], + ) + route_to_dst.add_vpp_config() + + # + # packets to these destination are dropped, since they'll + # hit the respective default routes in table 1 + # + p_dst = ( + Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) + / IPv6(src="5::5", dst="1::1") + / inet6.TCP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + pkts_dst = p_dst * 10 + + self.send_and_assert_no_replies(self.pg0, pkts_dst, "IP in table 1") + + # + # add a route in the dst table to forward via pg1 + # + route_in_dst = VppIpRoute( + self, + "1::1", + 128, + [VppRoutePath(self.pg1.remote_ip6, self.pg1.sw_if_index)], + table_id=1, + ) + route_in_dst.add_vpp_config() + + self.send_and_expect(self.pg0, pkts_dst, self.pg1) + + # + # add a route in the default table to receive ... + # + route_to_dst = VppIpRoute( + self, + "1::", + 122, + [ + VppRoutePath( + "::", + self.pg2.sw_if_index, + type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX, + ) + ], + table_id=1, + ) + route_to_dst.add_vpp_config() + + # + # packets to these destination are dropped, since they'll + # hit the respective default routes in table 2 + # + p_dst = ( + Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) + / IPv6(src="6::6", dst="1::2") + / inet6.TCP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + pkts_dst = p_dst * 10 + + self.send_and_assert_no_replies(self.pg0, pkts_dst, "IP in table 2") + + # + # add a route in the table 2 to forward via pg2 + # + route_in_dst = VppIpRoute( + self, + "1::2", + 128, + [VppRoutePath(self.pg2.remote_ip6, self.pg2.sw_if_index)], + table_id=2, + ) + route_in_dst.add_vpp_config() + + self.send_and_expect(self.pg0, pkts_dst, self.pg2) + + if __name__ == "__main__": unittest.main(testRunner=VppTestRunner) -- 2.16.6