/* * This selftest spins up a client and an echo server, each in their own * network namespace. The client will send a fragmented message to the server. * The prog attached to the server will shoot down any fragments. Thus, if * the server is able to correctly echo back the message to the client, we will * have verified that netfilter is reassembling packets for us. * * Topology: * ========= * NS0 | NS1 * | * client | server * ---------- | ---------- * | veth0 | --------- | veth1 | * ---------- peer ---------- * | * | with bpf
*/
#define NS0 "defrag_ns0" #define NS1 "defrag_ns1" #define VETH0 "veth0" #define VETH1 "veth1" #define VETH0_ADDR "172.16.1.100" #define VETH0_ADDR6 "fc00::100" /* The following constants must stay in sync with `generate_udp_fragments.py` */ #define VETH1_ADDR "172.16.1.200" #define VETH1_ADDR6 "fc00::200" #define CLIENT_PORT 48878 #define SERVER_PORT 48879 #define MAGIC_MESSAGE "THIS IS THE ORIGINAL MESSAGE, PLEASE REASSEMBLE ME"
staticint setup_topology(bool ipv6)
{ bool up; int i;
SYS(fail, "ip netns add " NS0);
SYS(fail, "ip netns add " NS1);
SYS(fail, "ip link add " VETH0 " netns " NS0 " type veth peer name " VETH1 " netns " NS1); if (ipv6) {
SYS(fail, "ip -6 -net " NS0 " addr add " VETH0_ADDR6 "/64 dev " VETH0 " nodad");
SYS(fail, "ip -6 -net " NS1 " addr add " VETH1_ADDR6 "/64 dev " VETH1 " nodad");
} else {
SYS(fail, "ip -net " NS0 " addr add " VETH0_ADDR "/24 dev " VETH0);
SYS(fail, "ip -net " NS1 " addr add " VETH1_ADDR "/24 dev " VETH1);
}
SYS(fail, "ip -net " NS0 " link set dev " VETH0 " up");
SYS(fail, "ip -net " NS1 " link set dev " VETH1 " up");
/* Wait for up to 5s for links to come up */ for (i = 0; i < 5; ++i) { if (ipv6)
up = !SYS_NOFAIL("ip netns exec " NS0 " ping -6 -c 1 -W 1 " VETH1_ADDR6); else
up = !SYS_NOFAIL("ip netns exec " NS0 " ping -c 1 -W 1 " VETH1_ADDR);
saddr_p = (struct sockaddr *)&saddr; /* Port needs to be set to 0 for raw ipv6 socket for some reason */
err = make_sockaddr(AF_INET6, VETH1_ADDR6, 0, &saddr, &saddr_len); if (!ASSERT_OK(err, "make_sockaddr")) return -1;
/* Send message in fragments */ if (ipv6) { if (!ASSERT_OK(send_frags6(client_tx_fd), "send_frags6")) goto out;
} else { if (!ASSERT_OK(send_frags(client_tx_fd), "send_frags")) goto out;
}
if (!ASSERT_EQ(skel->bss->shootdowns, 0, "shootdowns")) goto out;
/* Receive reassembled msg on server and echo back to client */
caddr_len = sizeof(caddr);
len = recvfrom(srv_fd, buf, sizeof(buf), 0, (struct sockaddr *)&caddr, &caddr_len); if (!ASSERT_GE(len, 0, "server recvfrom")) goto out;
len = sendto(srv_fd, buf, len, 0, (struct sockaddr *)&caddr, caddr_len); if (!ASSERT_GE(len, 0, "server sendto")) goto out;
/* Expect reassembed message to be echoed back */
len = recvfrom(client_rx_fd, buf, sizeof(buf), 0, NULL, NULL); if (!ASSERT_EQ(len, sizeof(MAGIC_MESSAGE) - 1, "client short read")) goto out;
out: if (client_rx_fd != -1)
close(client_rx_fd); if (client_tx_fd != -1)
close(client_tx_fd); if (srv_fd != -1)
close(srv_fd);
cleanup_topology();
ip_check_defrag__destroy(skel);
}
void test_bpf_ip_check_defrag(void)
{ if (test__start_subtest("v4"))
test_bpf_ip_check_defrag_ok(false); if (test__start_subtest("v6"))
test_bpf_ip_check_defrag_ok(true);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.