1*539c7e67SKui-Feng Lee // SPDX-License-Identifier: GPL-2.0 2*539c7e67SKui-Feng Lee /* Copyright (c) 2023 Facebook */ 3*539c7e67SKui-Feng Lee #include <test_progs.h> 4*539c7e67SKui-Feng Lee #include <linux/in6.h> 5*539c7e67SKui-Feng Lee #include <sys/socket.h> 6*539c7e67SKui-Feng Lee #include <sched.h> 7*539c7e67SKui-Feng Lee #include <unistd.h> 8*539c7e67SKui-Feng Lee #include "cgroup_helpers.h" 9*539c7e67SKui-Feng Lee #include "testing_helpers.h" 10*539c7e67SKui-Feng Lee #include "cgroup_tcp_skb.skel.h" 11*539c7e67SKui-Feng Lee #include "cgroup_tcp_skb.h" 12*539c7e67SKui-Feng Lee 13*539c7e67SKui-Feng Lee #define CGROUP_TCP_SKB_PATH "/test_cgroup_tcp_skb" 14*539c7e67SKui-Feng Lee 15*539c7e67SKui-Feng Lee static int install_filters(int cgroup_fd, 16*539c7e67SKui-Feng Lee struct bpf_link **egress_link, 17*539c7e67SKui-Feng Lee struct bpf_link **ingress_link, 18*539c7e67SKui-Feng Lee struct bpf_program *egress_prog, 19*539c7e67SKui-Feng Lee struct bpf_program *ingress_prog, 20*539c7e67SKui-Feng Lee struct cgroup_tcp_skb *skel) 21*539c7e67SKui-Feng Lee { 22*539c7e67SKui-Feng Lee /* Prepare filters */ 23*539c7e67SKui-Feng Lee skel->bss->g_sock_state = 0; 24*539c7e67SKui-Feng Lee skel->bss->g_unexpected = 0; 25*539c7e67SKui-Feng Lee *egress_link = 26*539c7e67SKui-Feng Lee bpf_program__attach_cgroup(egress_prog, 27*539c7e67SKui-Feng Lee cgroup_fd); 28*539c7e67SKui-Feng Lee if (!ASSERT_OK_PTR(egress_link, "egress_link")) 29*539c7e67SKui-Feng Lee return -1; 30*539c7e67SKui-Feng Lee *ingress_link = 31*539c7e67SKui-Feng Lee bpf_program__attach_cgroup(ingress_prog, 32*539c7e67SKui-Feng Lee cgroup_fd); 33*539c7e67SKui-Feng Lee if (!ASSERT_OK_PTR(ingress_link, "ingress_link")) 34*539c7e67SKui-Feng Lee return -1; 35*539c7e67SKui-Feng Lee 36*539c7e67SKui-Feng Lee return 0; 37*539c7e67SKui-Feng Lee } 38*539c7e67SKui-Feng Lee 39*539c7e67SKui-Feng Lee static void uninstall_filters(struct bpf_link **egress_link, 40*539c7e67SKui-Feng Lee struct bpf_link **ingress_link) 41*539c7e67SKui-Feng Lee { 42*539c7e67SKui-Feng Lee bpf_link__destroy(*egress_link); 43*539c7e67SKui-Feng Lee *egress_link = NULL; 44*539c7e67SKui-Feng Lee bpf_link__destroy(*ingress_link); 45*539c7e67SKui-Feng Lee *ingress_link = NULL; 46*539c7e67SKui-Feng Lee } 47*539c7e67SKui-Feng Lee 48*539c7e67SKui-Feng Lee static int create_client_sock_v6(void) 49*539c7e67SKui-Feng Lee { 50*539c7e67SKui-Feng Lee int fd; 51*539c7e67SKui-Feng Lee 52*539c7e67SKui-Feng Lee fd = socket(AF_INET6, SOCK_STREAM, 0); 53*539c7e67SKui-Feng Lee if (fd < 0) { 54*539c7e67SKui-Feng Lee perror("socket"); 55*539c7e67SKui-Feng Lee return -1; 56*539c7e67SKui-Feng Lee } 57*539c7e67SKui-Feng Lee 58*539c7e67SKui-Feng Lee return fd; 59*539c7e67SKui-Feng Lee } 60*539c7e67SKui-Feng Lee 61*539c7e67SKui-Feng Lee static int create_server_sock_v6(void) 62*539c7e67SKui-Feng Lee { 63*539c7e67SKui-Feng Lee struct sockaddr_in6 addr = { 64*539c7e67SKui-Feng Lee .sin6_family = AF_INET6, 65*539c7e67SKui-Feng Lee .sin6_port = htons(0), 66*539c7e67SKui-Feng Lee .sin6_addr = IN6ADDR_LOOPBACK_INIT, 67*539c7e67SKui-Feng Lee }; 68*539c7e67SKui-Feng Lee int fd, err; 69*539c7e67SKui-Feng Lee 70*539c7e67SKui-Feng Lee fd = socket(AF_INET6, SOCK_STREAM, 0); 71*539c7e67SKui-Feng Lee if (fd < 0) { 72*539c7e67SKui-Feng Lee perror("socket"); 73*539c7e67SKui-Feng Lee return -1; 74*539c7e67SKui-Feng Lee } 75*539c7e67SKui-Feng Lee 76*539c7e67SKui-Feng Lee err = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); 77*539c7e67SKui-Feng Lee if (err < 0) { 78*539c7e67SKui-Feng Lee perror("bind"); 79*539c7e67SKui-Feng Lee return -1; 80*539c7e67SKui-Feng Lee } 81*539c7e67SKui-Feng Lee 82*539c7e67SKui-Feng Lee err = listen(fd, 1); 83*539c7e67SKui-Feng Lee if (err < 0) { 84*539c7e67SKui-Feng Lee perror("listen"); 85*539c7e67SKui-Feng Lee return -1; 86*539c7e67SKui-Feng Lee } 87*539c7e67SKui-Feng Lee 88*539c7e67SKui-Feng Lee return fd; 89*539c7e67SKui-Feng Lee } 90*539c7e67SKui-Feng Lee 91*539c7e67SKui-Feng Lee static int get_sock_port_v6(int fd) 92*539c7e67SKui-Feng Lee { 93*539c7e67SKui-Feng Lee struct sockaddr_in6 addr; 94*539c7e67SKui-Feng Lee socklen_t len; 95*539c7e67SKui-Feng Lee int err; 96*539c7e67SKui-Feng Lee 97*539c7e67SKui-Feng Lee len = sizeof(addr); 98*539c7e67SKui-Feng Lee err = getsockname(fd, (struct sockaddr *)&addr, &len); 99*539c7e67SKui-Feng Lee if (err < 0) { 100*539c7e67SKui-Feng Lee perror("getsockname"); 101*539c7e67SKui-Feng Lee return -1; 102*539c7e67SKui-Feng Lee } 103*539c7e67SKui-Feng Lee 104*539c7e67SKui-Feng Lee return ntohs(addr.sin6_port); 105*539c7e67SKui-Feng Lee } 106*539c7e67SKui-Feng Lee 107*539c7e67SKui-Feng Lee static int connect_client_server_v6(int client_fd, int listen_fd) 108*539c7e67SKui-Feng Lee { 109*539c7e67SKui-Feng Lee struct sockaddr_in6 addr = { 110*539c7e67SKui-Feng Lee .sin6_family = AF_INET6, 111*539c7e67SKui-Feng Lee .sin6_addr = IN6ADDR_LOOPBACK_INIT, 112*539c7e67SKui-Feng Lee }; 113*539c7e67SKui-Feng Lee int err; 114*539c7e67SKui-Feng Lee 115*539c7e67SKui-Feng Lee addr.sin6_port = htons(get_sock_port_v6(listen_fd)); 116*539c7e67SKui-Feng Lee if (addr.sin6_port < 0) 117*539c7e67SKui-Feng Lee return -1; 118*539c7e67SKui-Feng Lee 119*539c7e67SKui-Feng Lee err = connect(client_fd, (struct sockaddr *)&addr, sizeof(addr)); 120*539c7e67SKui-Feng Lee if (err < 0) { 121*539c7e67SKui-Feng Lee perror("connect"); 122*539c7e67SKui-Feng Lee return -1; 123*539c7e67SKui-Feng Lee } 124*539c7e67SKui-Feng Lee 125*539c7e67SKui-Feng Lee return 0; 126*539c7e67SKui-Feng Lee } 127*539c7e67SKui-Feng Lee 128*539c7e67SKui-Feng Lee /* Connect to the server in a cgroup from the outside of the cgroup. */ 129*539c7e67SKui-Feng Lee static int talk_to_cgroup(int *client_fd, int *listen_fd, int *service_fd, 130*539c7e67SKui-Feng Lee struct cgroup_tcp_skb *skel) 131*539c7e67SKui-Feng Lee { 132*539c7e67SKui-Feng Lee int err, cp; 133*539c7e67SKui-Feng Lee char buf[5]; 134*539c7e67SKui-Feng Lee 135*539c7e67SKui-Feng Lee /* Create client & server socket */ 136*539c7e67SKui-Feng Lee err = join_root_cgroup(); 137*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "join_root_cgroup")) 138*539c7e67SKui-Feng Lee return -1; 139*539c7e67SKui-Feng Lee *client_fd = create_client_sock_v6(); 140*539c7e67SKui-Feng Lee if (!ASSERT_GE(*client_fd, 0, "client_fd")) 141*539c7e67SKui-Feng Lee return -1; 142*539c7e67SKui-Feng Lee err = join_cgroup(CGROUP_TCP_SKB_PATH); 143*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "join_cgroup")) 144*539c7e67SKui-Feng Lee return -1; 145*539c7e67SKui-Feng Lee *listen_fd = create_server_sock_v6(); 146*539c7e67SKui-Feng Lee if (!ASSERT_GE(*listen_fd, 0, "listen_fd")) 147*539c7e67SKui-Feng Lee return -1; 148*539c7e67SKui-Feng Lee skel->bss->g_sock_port = get_sock_port_v6(*listen_fd); 149*539c7e67SKui-Feng Lee 150*539c7e67SKui-Feng Lee /* Connect client to server */ 151*539c7e67SKui-Feng Lee err = connect_client_server_v6(*client_fd, *listen_fd); 152*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "connect_client_server_v6")) 153*539c7e67SKui-Feng Lee return -1; 154*539c7e67SKui-Feng Lee *service_fd = accept(*listen_fd, NULL, NULL); 155*539c7e67SKui-Feng Lee if (!ASSERT_GE(*service_fd, 0, "service_fd")) 156*539c7e67SKui-Feng Lee return -1; 157*539c7e67SKui-Feng Lee err = join_root_cgroup(); 158*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "join_root_cgroup")) 159*539c7e67SKui-Feng Lee return -1; 160*539c7e67SKui-Feng Lee cp = write(*client_fd, "hello", 5); 161*539c7e67SKui-Feng Lee if (!ASSERT_EQ(cp, 5, "write")) 162*539c7e67SKui-Feng Lee return -1; 163*539c7e67SKui-Feng Lee cp = read(*service_fd, buf, 5); 164*539c7e67SKui-Feng Lee if (!ASSERT_EQ(cp, 5, "read")) 165*539c7e67SKui-Feng Lee return -1; 166*539c7e67SKui-Feng Lee 167*539c7e67SKui-Feng Lee return 0; 168*539c7e67SKui-Feng Lee } 169*539c7e67SKui-Feng Lee 170*539c7e67SKui-Feng Lee /* Connect to the server out of a cgroup from inside the cgroup. */ 171*539c7e67SKui-Feng Lee static int talk_to_outside(int *client_fd, int *listen_fd, int *service_fd, 172*539c7e67SKui-Feng Lee struct cgroup_tcp_skb *skel) 173*539c7e67SKui-Feng Lee 174*539c7e67SKui-Feng Lee { 175*539c7e67SKui-Feng Lee int err, cp; 176*539c7e67SKui-Feng Lee char buf[5]; 177*539c7e67SKui-Feng Lee 178*539c7e67SKui-Feng Lee /* Create client & server socket */ 179*539c7e67SKui-Feng Lee err = join_root_cgroup(); 180*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "join_root_cgroup")) 181*539c7e67SKui-Feng Lee return -1; 182*539c7e67SKui-Feng Lee *listen_fd = create_server_sock_v6(); 183*539c7e67SKui-Feng Lee if (!ASSERT_GE(*listen_fd, 0, "listen_fd")) 184*539c7e67SKui-Feng Lee return -1; 185*539c7e67SKui-Feng Lee err = join_cgroup(CGROUP_TCP_SKB_PATH); 186*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "join_cgroup")) 187*539c7e67SKui-Feng Lee return -1; 188*539c7e67SKui-Feng Lee *client_fd = create_client_sock_v6(); 189*539c7e67SKui-Feng Lee if (!ASSERT_GE(*client_fd, 0, "client_fd")) 190*539c7e67SKui-Feng Lee return -1; 191*539c7e67SKui-Feng Lee err = join_root_cgroup(); 192*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "join_root_cgroup")) 193*539c7e67SKui-Feng Lee return -1; 194*539c7e67SKui-Feng Lee skel->bss->g_sock_port = get_sock_port_v6(*listen_fd); 195*539c7e67SKui-Feng Lee 196*539c7e67SKui-Feng Lee /* Connect client to server */ 197*539c7e67SKui-Feng Lee err = connect_client_server_v6(*client_fd, *listen_fd); 198*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "connect_client_server_v6")) 199*539c7e67SKui-Feng Lee return -1; 200*539c7e67SKui-Feng Lee *service_fd = accept(*listen_fd, NULL, NULL); 201*539c7e67SKui-Feng Lee if (!ASSERT_GE(*service_fd, 0, "service_fd")) 202*539c7e67SKui-Feng Lee return -1; 203*539c7e67SKui-Feng Lee cp = write(*client_fd, "hello", 5); 204*539c7e67SKui-Feng Lee if (!ASSERT_EQ(cp, 5, "write")) 205*539c7e67SKui-Feng Lee return -1; 206*539c7e67SKui-Feng Lee cp = read(*service_fd, buf, 5); 207*539c7e67SKui-Feng Lee if (!ASSERT_EQ(cp, 5, "read")) 208*539c7e67SKui-Feng Lee return -1; 209*539c7e67SKui-Feng Lee 210*539c7e67SKui-Feng Lee return 0; 211*539c7e67SKui-Feng Lee } 212*539c7e67SKui-Feng Lee 213*539c7e67SKui-Feng Lee static int close_connection(int *closing_fd, int *peer_fd, int *listen_fd, 214*539c7e67SKui-Feng Lee struct cgroup_tcp_skb *skel) 215*539c7e67SKui-Feng Lee { 216*539c7e67SKui-Feng Lee __u32 saved_packet_count = 0; 217*539c7e67SKui-Feng Lee int err; 218*539c7e67SKui-Feng Lee int i; 219*539c7e67SKui-Feng Lee 220*539c7e67SKui-Feng Lee /* Wait for ACKs to be sent */ 221*539c7e67SKui-Feng Lee saved_packet_count = skel->bss->g_packet_count; 222*539c7e67SKui-Feng Lee usleep(100000); /* 0.1s */ 223*539c7e67SKui-Feng Lee for (i = 0; 224*539c7e67SKui-Feng Lee skel->bss->g_packet_count != saved_packet_count && i < 10; 225*539c7e67SKui-Feng Lee i++) { 226*539c7e67SKui-Feng Lee saved_packet_count = skel->bss->g_packet_count; 227*539c7e67SKui-Feng Lee usleep(100000); /* 0.1s */ 228*539c7e67SKui-Feng Lee } 229*539c7e67SKui-Feng Lee if (!ASSERT_EQ(skel->bss->g_packet_count, saved_packet_count, 230*539c7e67SKui-Feng Lee "packet_count")) 231*539c7e67SKui-Feng Lee return -1; 232*539c7e67SKui-Feng Lee 233*539c7e67SKui-Feng Lee skel->bss->g_packet_count = 0; 234*539c7e67SKui-Feng Lee saved_packet_count = 0; 235*539c7e67SKui-Feng Lee 236*539c7e67SKui-Feng Lee /* Half shutdown to make sure the closing socket having a chance to 237*539c7e67SKui-Feng Lee * receive a FIN from the peer. 238*539c7e67SKui-Feng Lee */ 239*539c7e67SKui-Feng Lee err = shutdown(*closing_fd, SHUT_WR); 240*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "shutdown closing_fd")) 241*539c7e67SKui-Feng Lee return -1; 242*539c7e67SKui-Feng Lee 243*539c7e67SKui-Feng Lee /* Wait for FIN and the ACK of the FIN to be observed */ 244*539c7e67SKui-Feng Lee for (i = 0; 245*539c7e67SKui-Feng Lee skel->bss->g_packet_count < saved_packet_count + 2 && i < 10; 246*539c7e67SKui-Feng Lee i++) 247*539c7e67SKui-Feng Lee usleep(100000); /* 0.1s */ 248*539c7e67SKui-Feng Lee if (!ASSERT_GE(skel->bss->g_packet_count, saved_packet_count + 2, 249*539c7e67SKui-Feng Lee "packet_count")) 250*539c7e67SKui-Feng Lee return -1; 251*539c7e67SKui-Feng Lee 252*539c7e67SKui-Feng Lee saved_packet_count = skel->bss->g_packet_count; 253*539c7e67SKui-Feng Lee 254*539c7e67SKui-Feng Lee /* Fully shutdown the connection */ 255*539c7e67SKui-Feng Lee err = close(*peer_fd); 256*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "close peer_fd")) 257*539c7e67SKui-Feng Lee return -1; 258*539c7e67SKui-Feng Lee *peer_fd = -1; 259*539c7e67SKui-Feng Lee 260*539c7e67SKui-Feng Lee /* Wait for FIN and the ACK of the FIN to be observed */ 261*539c7e67SKui-Feng Lee for (i = 0; 262*539c7e67SKui-Feng Lee skel->bss->g_packet_count < saved_packet_count + 2 && i < 10; 263*539c7e67SKui-Feng Lee i++) 264*539c7e67SKui-Feng Lee usleep(100000); /* 0.1s */ 265*539c7e67SKui-Feng Lee if (!ASSERT_GE(skel->bss->g_packet_count, saved_packet_count + 2, 266*539c7e67SKui-Feng Lee "packet_count")) 267*539c7e67SKui-Feng Lee return -1; 268*539c7e67SKui-Feng Lee 269*539c7e67SKui-Feng Lee err = close(*closing_fd); 270*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "close closing_fd")) 271*539c7e67SKui-Feng Lee return -1; 272*539c7e67SKui-Feng Lee *closing_fd = -1; 273*539c7e67SKui-Feng Lee 274*539c7e67SKui-Feng Lee close(*listen_fd); 275*539c7e67SKui-Feng Lee *listen_fd = -1; 276*539c7e67SKui-Feng Lee 277*539c7e67SKui-Feng Lee return 0; 278*539c7e67SKui-Feng Lee } 279*539c7e67SKui-Feng Lee 280*539c7e67SKui-Feng Lee /* This test case includes four scenarios: 281*539c7e67SKui-Feng Lee * 1. Connect to the server from outside the cgroup and close the connection 282*539c7e67SKui-Feng Lee * from outside the cgroup. 283*539c7e67SKui-Feng Lee * 2. Connect to the server from outside the cgroup and close the connection 284*539c7e67SKui-Feng Lee * from inside the cgroup. 285*539c7e67SKui-Feng Lee * 3. Connect to the server from inside the cgroup and close the connection 286*539c7e67SKui-Feng Lee * from outside the cgroup. 287*539c7e67SKui-Feng Lee * 4. Connect to the server from inside the cgroup and close the connection 288*539c7e67SKui-Feng Lee * from inside the cgroup. 289*539c7e67SKui-Feng Lee * 290*539c7e67SKui-Feng Lee * The test case is to verify that cgroup_skb/{egress,ingress} filters 291*539c7e67SKui-Feng Lee * receive expected packets including SYN, SYN/ACK, ACK, FIN, and FIN/ACK. 292*539c7e67SKui-Feng Lee */ 293*539c7e67SKui-Feng Lee void test_cgroup_tcp_skb(void) 294*539c7e67SKui-Feng Lee { 295*539c7e67SKui-Feng Lee struct bpf_link *ingress_link = NULL; 296*539c7e67SKui-Feng Lee struct bpf_link *egress_link = NULL; 297*539c7e67SKui-Feng Lee int client_fd = -1, listen_fd = -1; 298*539c7e67SKui-Feng Lee struct cgroup_tcp_skb *skel; 299*539c7e67SKui-Feng Lee int service_fd = -1; 300*539c7e67SKui-Feng Lee int cgroup_fd = -1; 301*539c7e67SKui-Feng Lee int err; 302*539c7e67SKui-Feng Lee 303*539c7e67SKui-Feng Lee skel = cgroup_tcp_skb__open_and_load(); 304*539c7e67SKui-Feng Lee if (!ASSERT_OK(!skel, "skel_open_load")) 305*539c7e67SKui-Feng Lee return; 306*539c7e67SKui-Feng Lee 307*539c7e67SKui-Feng Lee err = setup_cgroup_environment(); 308*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "setup_cgroup_environment")) 309*539c7e67SKui-Feng Lee goto cleanup; 310*539c7e67SKui-Feng Lee 311*539c7e67SKui-Feng Lee cgroup_fd = create_and_get_cgroup(CGROUP_TCP_SKB_PATH); 312*539c7e67SKui-Feng Lee if (!ASSERT_GE(cgroup_fd, 0, "cgroup_fd")) 313*539c7e67SKui-Feng Lee goto cleanup; 314*539c7e67SKui-Feng Lee 315*539c7e67SKui-Feng Lee /* Scenario 1 */ 316*539c7e67SKui-Feng Lee err = install_filters(cgroup_fd, &egress_link, &ingress_link, 317*539c7e67SKui-Feng Lee skel->progs.server_egress, 318*539c7e67SKui-Feng Lee skel->progs.server_ingress, 319*539c7e67SKui-Feng Lee skel); 320*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "install_filters")) 321*539c7e67SKui-Feng Lee goto cleanup; 322*539c7e67SKui-Feng Lee 323*539c7e67SKui-Feng Lee err = talk_to_cgroup(&client_fd, &listen_fd, &service_fd, skel); 324*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "talk_to_cgroup")) 325*539c7e67SKui-Feng Lee goto cleanup; 326*539c7e67SKui-Feng Lee 327*539c7e67SKui-Feng Lee err = close_connection(&client_fd, &service_fd, &listen_fd, skel); 328*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "close_connection")) 329*539c7e67SKui-Feng Lee goto cleanup; 330*539c7e67SKui-Feng Lee 331*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected"); 332*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_sock_state, CLOSED, "g_sock_state"); 333*539c7e67SKui-Feng Lee 334*539c7e67SKui-Feng Lee uninstall_filters(&egress_link, &ingress_link); 335*539c7e67SKui-Feng Lee 336*539c7e67SKui-Feng Lee /* Scenario 2 */ 337*539c7e67SKui-Feng Lee err = install_filters(cgroup_fd, &egress_link, &ingress_link, 338*539c7e67SKui-Feng Lee skel->progs.server_egress_srv, 339*539c7e67SKui-Feng Lee skel->progs.server_ingress_srv, 340*539c7e67SKui-Feng Lee skel); 341*539c7e67SKui-Feng Lee 342*539c7e67SKui-Feng Lee err = talk_to_cgroup(&client_fd, &listen_fd, &service_fd, skel); 343*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "talk_to_cgroup")) 344*539c7e67SKui-Feng Lee goto cleanup; 345*539c7e67SKui-Feng Lee 346*539c7e67SKui-Feng Lee err = close_connection(&service_fd, &client_fd, &listen_fd, skel); 347*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "close_connection")) 348*539c7e67SKui-Feng Lee goto cleanup; 349*539c7e67SKui-Feng Lee 350*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected"); 351*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_sock_state, TIME_WAIT, "g_sock_state"); 352*539c7e67SKui-Feng Lee 353*539c7e67SKui-Feng Lee uninstall_filters(&egress_link, &ingress_link); 354*539c7e67SKui-Feng Lee 355*539c7e67SKui-Feng Lee /* Scenario 3 */ 356*539c7e67SKui-Feng Lee err = install_filters(cgroup_fd, &egress_link, &ingress_link, 357*539c7e67SKui-Feng Lee skel->progs.client_egress_srv, 358*539c7e67SKui-Feng Lee skel->progs.client_ingress_srv, 359*539c7e67SKui-Feng Lee skel); 360*539c7e67SKui-Feng Lee 361*539c7e67SKui-Feng Lee err = talk_to_outside(&client_fd, &listen_fd, &service_fd, skel); 362*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "talk_to_outside")) 363*539c7e67SKui-Feng Lee goto cleanup; 364*539c7e67SKui-Feng Lee 365*539c7e67SKui-Feng Lee err = close_connection(&service_fd, &client_fd, &listen_fd, skel); 366*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "close_connection")) 367*539c7e67SKui-Feng Lee goto cleanup; 368*539c7e67SKui-Feng Lee 369*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected"); 370*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_sock_state, CLOSED, "g_sock_state"); 371*539c7e67SKui-Feng Lee 372*539c7e67SKui-Feng Lee uninstall_filters(&egress_link, &ingress_link); 373*539c7e67SKui-Feng Lee 374*539c7e67SKui-Feng Lee /* Scenario 4 */ 375*539c7e67SKui-Feng Lee err = install_filters(cgroup_fd, &egress_link, &ingress_link, 376*539c7e67SKui-Feng Lee skel->progs.client_egress, 377*539c7e67SKui-Feng Lee skel->progs.client_ingress, 378*539c7e67SKui-Feng Lee skel); 379*539c7e67SKui-Feng Lee 380*539c7e67SKui-Feng Lee err = talk_to_outside(&client_fd, &listen_fd, &service_fd, skel); 381*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "talk_to_outside")) 382*539c7e67SKui-Feng Lee goto cleanup; 383*539c7e67SKui-Feng Lee 384*539c7e67SKui-Feng Lee err = close_connection(&client_fd, &service_fd, &listen_fd, skel); 385*539c7e67SKui-Feng Lee if (!ASSERT_OK(err, "close_connection")) 386*539c7e67SKui-Feng Lee goto cleanup; 387*539c7e67SKui-Feng Lee 388*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected"); 389*539c7e67SKui-Feng Lee ASSERT_EQ(skel->bss->g_sock_state, TIME_WAIT, "g_sock_state"); 390*539c7e67SKui-Feng Lee 391*539c7e67SKui-Feng Lee uninstall_filters(&egress_link, &ingress_link); 392*539c7e67SKui-Feng Lee 393*539c7e67SKui-Feng Lee cleanup: 394*539c7e67SKui-Feng Lee close(client_fd); 395*539c7e67SKui-Feng Lee close(listen_fd); 396*539c7e67SKui-Feng Lee close(service_fd); 397*539c7e67SKui-Feng Lee close(cgroup_fd); 398*539c7e67SKui-Feng Lee bpf_link__destroy(egress_link); 399*539c7e67SKui-Feng Lee bpf_link__destroy(ingress_link); 400*539c7e67SKui-Feng Lee cleanup_cgroup_environment(); 401*539c7e67SKui-Feng Lee cgroup_tcp_skb__destroy(skel); 402*539c7e67SKui-Feng Lee } 403