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