xref: /linux/tools/net/ynl/tests/rt-route.c (revision 91a4855d6c03e770e42f17c798a36a3c46e63de2)
1e0aa0c61SJakub Kicinski // SPDX-License-Identifier: GPL-2.0
2e0aa0c61SJakub Kicinski #include <stdio.h>
3e0aa0c61SJakub Kicinski #include <string.h>
4e0aa0c61SJakub Kicinski 
5e0aa0c61SJakub Kicinski #include <ynl.h>
6e0aa0c61SJakub Kicinski 
7e0aa0c61SJakub Kicinski #include <arpa/inet.h>
8e0aa0c61SJakub Kicinski #include <net/if.h>
9e0aa0c61SJakub Kicinski 
10*aa234faaSJakub Kicinski #include <kselftest_harness.h>
11*aa234faaSJakub Kicinski 
12e0aa0c61SJakub Kicinski #include "rt-route-user.h"
13e0aa0c61SJakub Kicinski 
14*aa234faaSJakub Kicinski static void rt_route_print(struct __test_metadata *_metadata,
15*aa234faaSJakub Kicinski 			   struct rt_route_getroute_rsp *r)
16e0aa0c61SJakub Kicinski {
17e0aa0c61SJakub Kicinski 	char ifname[IF_NAMESIZE];
18e0aa0c61SJakub Kicinski 	char route_str[64];
19e0aa0c61SJakub Kicinski 	const char *route;
20e0aa0c61SJakub Kicinski 	const char *name;
21e0aa0c61SJakub Kicinski 
22e0aa0c61SJakub Kicinski 	/* Ignore local */
23e0aa0c61SJakub Kicinski 	if (r->_hdr.rtm_table == RT_TABLE_LOCAL)
24e0aa0c61SJakub Kicinski 		return;
25e0aa0c61SJakub Kicinski 
26e0aa0c61SJakub Kicinski 	if (r->_present.oif) {
27e0aa0c61SJakub Kicinski 		name = if_indextoname(r->oif, ifname);
28*aa234faaSJakub Kicinski 		EXPECT_NE(NULL, name);
29e0aa0c61SJakub Kicinski 		if (name)
30*aa234faaSJakub Kicinski 			ksft_print_msg("oif: %-16s ", name);
31e0aa0c61SJakub Kicinski 	}
32e0aa0c61SJakub Kicinski 
33e0aa0c61SJakub Kicinski 	if (r->_len.dst) {
34e0aa0c61SJakub Kicinski 		route = inet_ntop(r->_hdr.rtm_family, r->dst,
35e0aa0c61SJakub Kicinski 				  route_str, sizeof(route_str));
36e0aa0c61SJakub Kicinski 		printf("dst: %s/%d", route, r->_hdr.rtm_dst_len);
37e0aa0c61SJakub Kicinski 	}
38e0aa0c61SJakub Kicinski 
39e0aa0c61SJakub Kicinski 	if (r->_len.gateway) {
40e0aa0c61SJakub Kicinski 		route = inet_ntop(r->_hdr.rtm_family, r->gateway,
41e0aa0c61SJakub Kicinski 				  route_str, sizeof(route_str));
42e0aa0c61SJakub Kicinski 		printf("gateway: %s ", route);
43e0aa0c61SJakub Kicinski 	}
44e0aa0c61SJakub Kicinski 
45e0aa0c61SJakub Kicinski 	printf("\n");
46e0aa0c61SJakub Kicinski }
47e0aa0c61SJakub Kicinski 
48*aa234faaSJakub Kicinski FIXTURE(rt_route)
49*aa234faaSJakub Kicinski {
50*aa234faaSJakub Kicinski 	struct ynl_sock *ys;
51*aa234faaSJakub Kicinski };
52*aa234faaSJakub Kicinski 
53*aa234faaSJakub Kicinski FIXTURE_SETUP(rt_route)
54*aa234faaSJakub Kicinski {
55*aa234faaSJakub Kicinski 	struct ynl_error yerr;
56*aa234faaSJakub Kicinski 
57*aa234faaSJakub Kicinski 	self->ys = ynl_sock_create(&ynl_rt_route_family, &yerr);
58*aa234faaSJakub Kicinski 	ASSERT_NE(NULL, self->ys)
59*aa234faaSJakub Kicinski 		TH_LOG("failed to create rt-route socket: %s", yerr.msg);
60*aa234faaSJakub Kicinski }
61*aa234faaSJakub Kicinski 
62*aa234faaSJakub Kicinski FIXTURE_TEARDOWN(rt_route)
63*aa234faaSJakub Kicinski {
64*aa234faaSJakub Kicinski 	ynl_sock_destroy(self->ys);
65*aa234faaSJakub Kicinski }
66*aa234faaSJakub Kicinski 
67*aa234faaSJakub Kicinski TEST_F(rt_route, dump)
68e0aa0c61SJakub Kicinski {
69e0aa0c61SJakub Kicinski 	struct rt_route_getroute_req_dump *req;
70e0aa0c61SJakub Kicinski 	struct rt_route_getroute_list *rsp;
71*aa234faaSJakub Kicinski 	struct in6_addr v6_expected;
72*aa234faaSJakub Kicinski 	struct in_addr v4_expected;
73*aa234faaSJakub Kicinski 	bool found_v4 = false;
74*aa234faaSJakub Kicinski 	bool found_v6 = false;
75e0aa0c61SJakub Kicinski 
76*aa234faaSJakub Kicinski 	/* The bash wrapper configures 192.168.1.1/24 and 2001:db8::1/64,
77*aa234faaSJakub Kicinski 	 * make sure we can find the connected routes in the dump.
78*aa234faaSJakub Kicinski 	 */
79*aa234faaSJakub Kicinski 	inet_pton(AF_INET, "192.168.1.0", &v4_expected);
80*aa234faaSJakub Kicinski 	inet_pton(AF_INET6, "2001:db8::", &v6_expected);
81e0aa0c61SJakub Kicinski 
82e0aa0c61SJakub Kicinski 	req = rt_route_getroute_req_dump_alloc();
83*aa234faaSJakub Kicinski 	ASSERT_NE(NULL, req);
84e0aa0c61SJakub Kicinski 
85*aa234faaSJakub Kicinski 	rsp = rt_route_getroute_dump(self->ys, req);
86e0aa0c61SJakub Kicinski 	rt_route_getroute_req_dump_free(req);
87*aa234faaSJakub Kicinski 	ASSERT_NE(NULL, rsp) {
88*aa234faaSJakub Kicinski 		TH_LOG("dump failed: %s", self->ys->err.msg);
89*aa234faaSJakub Kicinski 	}
90e0aa0c61SJakub Kicinski 
91*aa234faaSJakub Kicinski 	ASSERT_FALSE(ynl_dump_empty(rsp)) {
92*aa234faaSJakub Kicinski 		rt_route_getroute_list_free(rsp);
93*aa234faaSJakub Kicinski 		TH_LOG("no routes reported");
94*aa234faaSJakub Kicinski 	}
95*aa234faaSJakub Kicinski 
96*aa234faaSJakub Kicinski 	ynl_dump_foreach(rsp, route) {
97*aa234faaSJakub Kicinski 		rt_route_print(_metadata, route);
98*aa234faaSJakub Kicinski 
99*aa234faaSJakub Kicinski 		if (route->_hdr.rtm_table == RT_TABLE_LOCAL)
100*aa234faaSJakub Kicinski 			continue;
101*aa234faaSJakub Kicinski 
102*aa234faaSJakub Kicinski 		if (route->_len.dst == 4 && route->_hdr.rtm_dst_len == 24)
103*aa234faaSJakub Kicinski 			found_v4 |= !memcmp(route->dst, &v4_expected, 4);
104*aa234faaSJakub Kicinski 		if (route->_len.dst == 16 && route->_hdr.rtm_dst_len == 64)
105*aa234faaSJakub Kicinski 			found_v6 |= !memcmp(route->dst, &v6_expected, 16);
106*aa234faaSJakub Kicinski 	}
107e0aa0c61SJakub Kicinski 	rt_route_getroute_list_free(rsp);
108e0aa0c61SJakub Kicinski 
109*aa234faaSJakub Kicinski 	EXPECT_TRUE(found_v4);
110*aa234faaSJakub Kicinski 	EXPECT_TRUE(found_v6);
111e0aa0c61SJakub Kicinski }
112*aa234faaSJakub Kicinski 
113*aa234faaSJakub Kicinski TEST_HARNESS_MAIN
114