mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 12:56:48 +00:00
Add netlink regression test and gVisor test
This commit is contained in:
parent
7d24e63216
commit
5e9f537222
@ -70,6 +70,9 @@ $(INITRAMFS)/lib/x86_64-linux-gnu: | $(VDSO_LIB)
|
||||
@cp -L /lib/x86_64-linux-gnu/libevent-2.1.so.7 $@
|
||||
@# required for VDSO
|
||||
@cp -L $(VDSO_LIB) $@
|
||||
@# required for netlink test
|
||||
@cp -L /lib/x86_64-linux-gnu/libnl-3.so.200 $@
|
||||
@cp -L /lib/x86_64-linux-gnu/libnl-route-3.so.200 $@
|
||||
|
||||
$(VDSO_LIB): | $(VDSO_DIR) $(BINARY_CACHE_DIR)/vdso64.so
|
||||
@# TODO: use a custom compiled vdso.so file in the future.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
include ../test_common.mk
|
||||
|
||||
EXTRA_C_FLAGS :=
|
||||
EXTRA_C_FLAGS := -I/usr/include/libnl3 -lnl-3 -lnl-route-3
|
||||
|
227
test/apps/network/netlink_route.c
Normal file
227
test/apps/network/netlink_route.c
Normal file
@ -0,0 +1,227 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/link.h>
|
||||
#include <netlink/route/addr.h>
|
||||
#include <net/if.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#define ETHER_NAME "eth0"
|
||||
#define LOOPBACK_NAME "lo"
|
||||
|
||||
#define SUCC(expr) ((expr), 0)
|
||||
|
||||
int find_lo_and_eth0_by_libc(struct if_nameindex *if_ni)
|
||||
{
|
||||
int found_links = 0;
|
||||
|
||||
for (struct if_nameindex *i = if_ni;
|
||||
!(i->if_index == 0 && i->if_name == NULL); i++) {
|
||||
if (strcmp(i->if_name, LOOPBACK_NAME) == 0) {
|
||||
found_links++;
|
||||
}
|
||||
|
||||
if (strcmp(i->if_name, ETHER_NAME) == 0) {
|
||||
found_links++;
|
||||
}
|
||||
}
|
||||
|
||||
return found_links;
|
||||
}
|
||||
|
||||
FN_TEST(if_nameindex)
|
||||
{
|
||||
struct if_nameindex *if_ni;
|
||||
|
||||
CHECK_WITH(SUCC(if_ni = if_nameindex()), if_ni != NULL);
|
||||
|
||||
TEST_RES(find_lo_and_eth0_by_libc(if_ni), _ret == 2);
|
||||
|
||||
if_freenameindex(if_ni);
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
void find_lo_and_eth0_by_libnl(struct nl_object *obj, void *arg)
|
||||
{
|
||||
int *found_links = (int *)arg;
|
||||
struct rtnl_link *link = (struct rtnl_link *)obj;
|
||||
|
||||
if (strcmp(rtnl_link_get_name(link), LOOPBACK_NAME) == 0) {
|
||||
*found_links += 1;
|
||||
}
|
||||
|
||||
if (strcmp(rtnl_link_get_name(link), ETHER_NAME) == 0) {
|
||||
*found_links += 1;
|
||||
}
|
||||
}
|
||||
|
||||
FN_TEST(get_link_by_libnl)
|
||||
{
|
||||
struct nl_sock *sock;
|
||||
struct nl_cache *link_cache;
|
||||
|
||||
// 1. Create netlink socket and connect
|
||||
sock = nl_socket_alloc();
|
||||
TEST_RES(nl_connect(sock, NETLINK_ROUTE), _ret >= 0);
|
||||
|
||||
// 2. Allocate and retrieve link cache
|
||||
TEST_RES(rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache),
|
||||
_ret >= 0);
|
||||
|
||||
// 3. Iterate over all links to find lo and eth0
|
||||
int found_links = 0;
|
||||
TEST_RES(SUCC(nl_cache_foreach(link_cache, find_lo_and_eth0_by_libnl,
|
||||
&found_links)),
|
||||
found_links == 2);
|
||||
|
||||
// 4. Cleanup
|
||||
nl_cache_free(link_cache);
|
||||
nl_close(sock);
|
||||
nl_socket_free(sock);
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
void find_loopback_address(struct nl_object *obj, void *arg)
|
||||
{
|
||||
int *found_loopback = (int *)arg;
|
||||
struct rtnl_addr *addr = (struct rtnl_addr *)obj;
|
||||
struct nl_addr *local;
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
int family = rtnl_addr_get_family(addr);
|
||||
if (family != AF_INET) {
|
||||
return;
|
||||
}
|
||||
|
||||
local = rtnl_addr_get_local(addr);
|
||||
if (local) {
|
||||
nl_addr2str(local, buf, sizeof(buf));
|
||||
if (strcmp(buf, "127.0.0.1/8") == 0) {
|
||||
*found_loopback = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FN_TEST(get_loopback_address)
|
||||
{
|
||||
struct nl_sock *sock;
|
||||
struct nl_cache *addr_cache;
|
||||
|
||||
// 1. Create netlink socket and connect
|
||||
sock = nl_socket_alloc();
|
||||
TEST_RES(nl_connect(sock, NETLINK_ROUTE), _ret >= 0);
|
||||
|
||||
// 2. Allocate and retrieve address cache
|
||||
TEST_RES(rtnl_addr_alloc_cache(sock, &addr_cache), _ret >= 0);
|
||||
|
||||
// 3. Iterate over all addresses to find loopback address
|
||||
int found_loopback = 0;
|
||||
TEST_RES(SUCC(nl_cache_foreach(addr_cache, find_loopback_address,
|
||||
&found_loopback)),
|
||||
found_loopback == 1);
|
||||
|
||||
// 4. Cleanup
|
||||
nl_cache_free(addr_cache);
|
||||
nl_close(sock);
|
||||
nl_socket_free(sock);
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
int find_new_addr_until_done(char *buffer, size_t len, int *found_new_addr)
|
||||
{
|
||||
struct nlmsghdr *nlh = (struct nlmsghdr *)buffer;
|
||||
|
||||
for (; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
|
||||
if (nlh->nlmsg_type == NLMSG_DONE) {
|
||||
return *found_new_addr ? 1 : -1;
|
||||
}
|
||||
|
||||
if (nlh->nlmsg_type == RTM_NEWADDR) {
|
||||
*found_new_addr += 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FN_TEST(get_addr_error)
|
||||
{
|
||||
#define BUFFER_SIZE 8192
|
||||
|
||||
struct nl_req {
|
||||
struct nlmsghdr hdr;
|
||||
struct ifaddrmsg ifa;
|
||||
};
|
||||
|
||||
int sock_fd;
|
||||
struct sockaddr_nl sa;
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
sock_fd = TEST_SUCC(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE));
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.nl_family = AF_NETLINK;
|
||||
|
||||
TEST_SUCC(bind(sock_fd, (struct sockaddr *)&sa, sizeof(sa)));
|
||||
|
||||
// 1. Without NLM_F_DUMP flag
|
||||
struct nl_req req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
||||
req.hdr.nlmsg_type = RTM_GETADDR;
|
||||
req.hdr.nlmsg_flags = NLM_F_REQUEST;
|
||||
req.hdr.nlmsg_seq = 1;
|
||||
req.ifa.ifa_family = AF_UNSPEC;
|
||||
|
||||
struct iovec iov = { &req, req.hdr.nlmsg_len };
|
||||
struct msghdr msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
|
||||
|
||||
TEST_SUCC(sendmsg(sock_fd, &msg, 0));
|
||||
TEST_RES(recv(sock_fd, buffer, BUFFER_SIZE, 0),
|
||||
((struct nlmsghdr *)buffer)->nlmsg_type == NLMSG_ERROR &&
|
||||
((struct nlmsgerr *)NLMSG_DATA(buffer))->error ==
|
||||
-EOPNOTSUPP);
|
||||
|
||||
// 2. Invalid required index
|
||||
req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP | NLM_F_ACK;
|
||||
req.ifa.ifa_index = 9999;
|
||||
TEST_SUCC(sendmsg(sock_fd, &msg, 0));
|
||||
|
||||
int found_new_addr = 0;
|
||||
while (1) {
|
||||
size_t recv_len =
|
||||
TEST_SUCC(recv(sock_fd, buffer, BUFFER_SIZE, 0));
|
||||
|
||||
int found_done = TEST_SUCC(find_new_addr_until_done(
|
||||
buffer, recv_len, &found_new_addr));
|
||||
|
||||
if (found_done != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Invalid required family
|
||||
req.ifa.ifa_family = 255;
|
||||
req.ifa.ifa_index = 0;
|
||||
TEST_SUCC(sendmsg(sock_fd, &msg, 0));
|
||||
|
||||
found_new_addr = 0;
|
||||
while (1) {
|
||||
size_t recv_len =
|
||||
TEST_SUCC(recv(sock_fd, buffer, BUFFER_SIZE, 0));
|
||||
|
||||
int found_done = TEST_SUCC(find_new_addr_until_done(
|
||||
buffer, recv_len, &found_new_addr));
|
||||
|
||||
if (found_done != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
END_TEST()
|
@ -22,7 +22,7 @@ $(OBJ_OUTPUT_DIR) $(DEP_OUTPUT_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
$(OBJ_OUTPUT_DIR)/%: %.c | $(OBJ_OUTPUT_DIR) $(DEP_OUTPUT_DIR)
|
||||
@$(CC) $(C_FLAGS) $(EXTRA_C_FLAGS) $< -o $@ \
|
||||
@$(CC) $(C_FLAGS) $< -o $@ $(EXTRA_C_FLAGS) \
|
||||
-MMD -MF $(DEP_OUTPUT_DIR)/$*.d
|
||||
@echo "CC <= $@"
|
||||
|
||||
|
@ -46,6 +46,7 @@ TESTS ?= \
|
||||
sigaction_test \
|
||||
sigaltstack_test \
|
||||
signalfd_test \
|
||||
socket_netlink_route_test \
|
||||
stat_test \
|
||||
stat_times_test \
|
||||
statfs_test \
|
||||
|
12
test/syscall_test/blocklists/socket_netlink_route_test
Normal file
12
test/syscall_test/blocklists/socket_netlink_route_test
Normal file
@ -0,0 +1,12 @@
|
||||
NetlinkRouteTest.MsgHdrMsgUnsuppType
|
||||
NetlinkRouteTest.MsgHdrMsgTrunc
|
||||
NetlinkRouteTest.MsgTruncMsgHdrMsgTrunc
|
||||
NetlinkRouteTest.ControlMessageIgnored
|
||||
NetlinkRouteTest.AddAddr
|
||||
NetlinkRouteTest.GetRouteDump
|
||||
NetlinkRouteTest.GetRouteRequest
|
||||
NetlinkRouteTest.RecvmsgTrunc
|
||||
NetlinkRouteTest.RecvmsgTruncPeek
|
||||
NetlinkRouteTest.NoPasscredNoCreds
|
||||
NetlinkRouteTest.PasscredCreds
|
||||
NetlinkRouteTest/SockOptTest.GetSockOpt/*
|
Loading…
x
Reference in New Issue
Block a user