/* Connect to the server in a cgroup from the outside of the cgroup. */ staticint talk_to_cgroup(int *client_fd, int *listen_fd, int *service_fd, struct cgroup_tcp_skb *skel)
{ int err, cp; char buf[5]; int port;
/* Create client & server socket */
err = join_root_cgroup(); if (!ASSERT_OK(err, "join_root_cgroup")) return -1;
*client_fd = create_client_sock_v6(); if (!ASSERT_GE(*client_fd, 0, "client_fd")) return -1;
err = join_cgroup(CGROUP_TCP_SKB_PATH); if (!ASSERT_OK(err, "join_cgroup")) return -1;
*listen_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0); if (!ASSERT_GE(*listen_fd, 0, "listen_fd")) return -1;
port = get_socket_local_port(*listen_fd); if (!ASSERT_GE(port, 0, "get_socket_local_port")) return -1;
skel->bss->g_sock_port = ntohs(port);
/* Connect client to server */
err = connect_fd_to_fd(*client_fd, *listen_fd, 0); if (!ASSERT_OK(err, "connect_fd_to_fd")) return -1;
*service_fd = accept(*listen_fd, NULL, NULL); if (!ASSERT_GE(*service_fd, 0, "service_fd")) return -1;
err = join_root_cgroup(); if (!ASSERT_OK(err, "join_root_cgroup")) return -1;
cp = write(*client_fd, "hello", 5); if (!ASSERT_EQ(cp, 5, "write")) return -1;
cp = read(*service_fd, buf, 5); if (!ASSERT_EQ(cp, 5, "read")) return -1;
return 0;
}
/* Connect to the server out of a cgroup from inside the cgroup. */ staticint talk_to_outside(int *client_fd, int *listen_fd, int *service_fd, struct cgroup_tcp_skb *skel)
{ int err, cp; char buf[5]; int port;
/* Create client & server socket */
err = join_root_cgroup(); if (!ASSERT_OK(err, "join_root_cgroup")) return -1;
*listen_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0); if (!ASSERT_GE(*listen_fd, 0, "listen_fd")) return -1;
err = join_cgroup(CGROUP_TCP_SKB_PATH); if (!ASSERT_OK(err, "join_cgroup")) return -1;
*client_fd = create_client_sock_v6(); if (!ASSERT_GE(*client_fd, 0, "client_fd")) return -1;
err = join_root_cgroup(); if (!ASSERT_OK(err, "join_root_cgroup")) return -1;
port = get_socket_local_port(*listen_fd); if (!ASSERT_GE(port, 0, "get_socket_local_port")) return -1;
skel->bss->g_sock_port = ntohs(port);
/* Connect client to server */
err = connect_fd_to_fd(*client_fd, *listen_fd, 0); if (!ASSERT_OK(err, "connect_fd_to_fd")) return -1;
*service_fd = accept(*listen_fd, NULL, NULL); if (!ASSERT_GE(*service_fd, 0, "service_fd")) return -1;
cp = write(*client_fd, "hello", 5); if (!ASSERT_EQ(cp, 5, "write")) return -1;
cp = read(*service_fd, buf, 5); if (!ASSERT_EQ(cp, 5, "read")) return -1;
return 0;
}
staticint close_connection(int *closing_fd, int *peer_fd, int *listen_fd, struct cgroup_tcp_skb *skel)
{
__u32 saved_packet_count = 0; int err; int i;
/* Wait for ACKs to be sent */
saved_packet_count = skel->bss->g_packet_count;
usleep(100000); /* 0.1s */ for (i = 0;
skel->bss->g_packet_count != saved_packet_count && i < 10;
i++) {
saved_packet_count = skel->bss->g_packet_count;
usleep(100000); /* 0.1s */
} if (!ASSERT_EQ(skel->bss->g_packet_count, saved_packet_count, "packet_count")) return -1;
/* Half shutdown to make sure the closing socket having a chance to * receive a FIN from the peer.
*/
err = shutdown(*closing_fd, SHUT_WR); if (!ASSERT_OK(err, "shutdown closing_fd")) return -1;
/* Wait for FIN and the ACK of the FIN to be observed */ for (i = 0;
skel->bss->g_packet_count < saved_packet_count + 2 && i < 10;
i++)
usleep(100000); /* 0.1s */ if (!ASSERT_GE(skel->bss->g_packet_count, saved_packet_count + 2, "packet_count")) return -1;
saved_packet_count = skel->bss->g_packet_count;
/* Fully shutdown the connection */
err = close(*peer_fd); if (!ASSERT_OK(err, "close peer_fd")) return -1;
*peer_fd = -1;
/* Wait for FIN and the ACK of the FIN to be observed */ for (i = 0;
skel->bss->g_packet_count < saved_packet_count + 2 && i < 10;
i++)
usleep(100000); /* 0.1s */ if (!ASSERT_GE(skel->bss->g_packet_count, saved_packet_count + 2, "packet_count")) return -1;
/* This test case includes four scenarios: * 1. Connect to the server from outside the cgroup and close the connection * from outside the cgroup. * 2. Connect to the server from outside the cgroup and close the connection * from inside the cgroup. * 3. Connect to the server from inside the cgroup and close the connection * from outside the cgroup. * 4. Connect to the server from inside the cgroup and close the connection * from inside the cgroup. * * The test case is to verify that cgroup_skb/{egress,ingress} filters * receive expected packets including SYN, SYN/ACK, ACK, FIN, and FIN/ACK.
*/ void test_cgroup_tcp_skb(void)
{ struct bpf_link *ingress_link = NULL; struct bpf_link *egress_link = NULL; int client_fd = -1, listen_fd = -1; struct cgroup_tcp_skb *skel; int service_fd = -1; int cgroup_fd = -1; int err;
skel = cgroup_tcp_skb__open_and_load(); if (!ASSERT_OK(!skel, "skel_open_load")) return;
err = setup_cgroup_environment(); if (!ASSERT_OK(err, "setup_cgroup_environment")) goto cleanup;
cgroup_fd = create_and_get_cgroup(CGROUP_TCP_SKB_PATH); if (!ASSERT_GE(cgroup_fd, 0, "cgroup_fd")) goto cleanup;
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.