| // SPDX-License-Identifier: GPL-2.0 |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include <ynl.h> |
| |
| #include <arpa/inet.h> |
| #include <net/if.h> |
| |
| #include <kselftest_harness.h> |
| |
| #include "rt-route-user.h" |
| |
| static void rt_route_print(struct __test_metadata *_metadata, |
| struct rt_route_getroute_rsp *r) |
| { |
| char ifname[IF_NAMESIZE]; |
| char route_str[64]; |
| const char *route; |
| const char *name; |
| |
| /* Ignore local */ |
| if (r->_hdr.rtm_table == RT_TABLE_LOCAL) |
| return; |
| |
| if (r->_present.oif) { |
| name = if_indextoname(r->oif, ifname); |
| EXPECT_NE(NULL, name); |
| if (name) |
| ksft_print_msg("oif: %-16s ", name); |
| } |
| |
| if (r->_len.dst) { |
| route = inet_ntop(r->_hdr.rtm_family, r->dst, |
| route_str, sizeof(route_str)); |
| printf("dst: %s/%d", route, r->_hdr.rtm_dst_len); |
| } |
| |
| if (r->_len.gateway) { |
| route = inet_ntop(r->_hdr.rtm_family, r->gateway, |
| route_str, sizeof(route_str)); |
| printf("gateway: %s ", route); |
| } |
| |
| printf("\n"); |
| } |
| |
| FIXTURE(rt_route) |
| { |
| struct ynl_sock *ys; |
| }; |
| |
| FIXTURE_SETUP(rt_route) |
| { |
| struct ynl_error yerr; |
| |
| self->ys = ynl_sock_create(&ynl_rt_route_family, &yerr); |
| ASSERT_NE(NULL, self->ys) |
| TH_LOG("failed to create rt-route socket: %s", yerr.msg); |
| } |
| |
| FIXTURE_TEARDOWN(rt_route) |
| { |
| ynl_sock_destroy(self->ys); |
| } |
| |
| TEST_F(rt_route, dump) |
| { |
| struct rt_route_getroute_req_dump *req; |
| struct rt_route_getroute_list *rsp; |
| struct in6_addr v6_expected; |
| struct in_addr v4_expected; |
| bool found_v4 = false; |
| bool found_v6 = false; |
| |
| /* The bash wrapper configures 192.168.1.1/24 and 2001:db8::1/64, |
| * make sure we can find the connected routes in the dump. |
| */ |
| inet_pton(AF_INET, "192.168.1.0", &v4_expected); |
| inet_pton(AF_INET6, "2001:db8::", &v6_expected); |
| |
| req = rt_route_getroute_req_dump_alloc(); |
| ASSERT_NE(NULL, req); |
| |
| rsp = rt_route_getroute_dump(self->ys, req); |
| rt_route_getroute_req_dump_free(req); |
| ASSERT_NE(NULL, rsp) { |
| TH_LOG("dump failed: %s", self->ys->err.msg); |
| } |
| |
| ASSERT_FALSE(ynl_dump_empty(rsp)) { |
| rt_route_getroute_list_free(rsp); |
| TH_LOG("no routes reported"); |
| } |
| |
| ynl_dump_foreach(rsp, route) { |
| rt_route_print(_metadata, route); |
| |
| if (route->_hdr.rtm_table == RT_TABLE_LOCAL) |
| continue; |
| |
| if (route->_len.dst == 4 && route->_hdr.rtm_dst_len == 24) |
| found_v4 |= !memcmp(route->dst, &v4_expected, 4); |
| if (route->_len.dst == 16 && route->_hdr.rtm_dst_len == 64) |
| found_v6 |= !memcmp(route->dst, &v6_expected, 16); |
| } |
| rt_route_getroute_list_free(rsp); |
| |
| EXPECT_TRUE(found_v4); |
| EXPECT_TRUE(found_v6); |
| } |
| |
| TEST_HARNESS_MAIN |