1539c7e67SKui-Feng Lee // SPDX-License-Identifier: GPL-2.0
2539c7e67SKui-Feng Lee /* Copyright (c) 2023 Facebook */
3539c7e67SKui-Feng Lee #include <test_progs.h>
4539c7e67SKui-Feng Lee #include <linux/in6.h>
5539c7e67SKui-Feng Lee #include <sys/socket.h>
6539c7e67SKui-Feng Lee #include <sched.h>
7539c7e67SKui-Feng Lee #include <unistd.h>
8539c7e67SKui-Feng Lee #include "cgroup_helpers.h"
9539c7e67SKui-Feng Lee #include "testing_helpers.h"
10539c7e67SKui-Feng Lee #include "cgroup_tcp_skb.skel.h"
11539c7e67SKui-Feng Lee #include "cgroup_tcp_skb.h"
12*96ead1e7SKui-Feng Lee #include "network_helpers.h"
13539c7e67SKui-Feng Lee 
14539c7e67SKui-Feng Lee #define CGROUP_TCP_SKB_PATH "/test_cgroup_tcp_skb"
15539c7e67SKui-Feng Lee 
install_filters(int cgroup_fd,struct bpf_link ** egress_link,struct bpf_link ** ingress_link,struct bpf_program * egress_prog,struct bpf_program * ingress_prog,struct cgroup_tcp_skb * skel)16539c7e67SKui-Feng Lee static int install_filters(int cgroup_fd,
17539c7e67SKui-Feng Lee 			   struct bpf_link **egress_link,
18539c7e67SKui-Feng Lee 			   struct bpf_link **ingress_link,
19539c7e67SKui-Feng Lee 			   struct bpf_program *egress_prog,
20539c7e67SKui-Feng Lee 			   struct bpf_program *ingress_prog,
21539c7e67SKui-Feng Lee 			   struct cgroup_tcp_skb *skel)
22539c7e67SKui-Feng Lee {
23539c7e67SKui-Feng Lee 	/* Prepare filters */
24539c7e67SKui-Feng Lee 	skel->bss->g_sock_state = 0;
25539c7e67SKui-Feng Lee 	skel->bss->g_unexpected = 0;
26539c7e67SKui-Feng Lee 	*egress_link =
27539c7e67SKui-Feng Lee 		bpf_program__attach_cgroup(egress_prog,
28539c7e67SKui-Feng Lee 					   cgroup_fd);
29539c7e67SKui-Feng Lee 	if (!ASSERT_OK_PTR(egress_link, "egress_link"))
30539c7e67SKui-Feng Lee 		return -1;
31539c7e67SKui-Feng Lee 	*ingress_link =
32539c7e67SKui-Feng Lee 		bpf_program__attach_cgroup(ingress_prog,
33539c7e67SKui-Feng Lee 					   cgroup_fd);
34539c7e67SKui-Feng Lee 	if (!ASSERT_OK_PTR(ingress_link, "ingress_link"))
35539c7e67SKui-Feng Lee 		return -1;
36539c7e67SKui-Feng Lee 
37539c7e67SKui-Feng Lee 	return 0;
38539c7e67SKui-Feng Lee }
39539c7e67SKui-Feng Lee 
uninstall_filters(struct bpf_link ** egress_link,struct bpf_link ** ingress_link)40539c7e67SKui-Feng Lee static void uninstall_filters(struct bpf_link **egress_link,
41539c7e67SKui-Feng Lee 			      struct bpf_link **ingress_link)
42539c7e67SKui-Feng Lee {
43539c7e67SKui-Feng Lee 	bpf_link__destroy(*egress_link);
44539c7e67SKui-Feng Lee 	*egress_link = NULL;
45539c7e67SKui-Feng Lee 	bpf_link__destroy(*ingress_link);
46539c7e67SKui-Feng Lee 	*ingress_link = NULL;
47539c7e67SKui-Feng Lee }
48539c7e67SKui-Feng Lee 
create_client_sock_v6(void)49539c7e67SKui-Feng Lee static int create_client_sock_v6(void)
50539c7e67SKui-Feng Lee {
51539c7e67SKui-Feng Lee 	int fd;
52539c7e67SKui-Feng Lee 
53539c7e67SKui-Feng Lee 	fd = socket(AF_INET6, SOCK_STREAM, 0);
54539c7e67SKui-Feng Lee 	if (fd < 0) {
55539c7e67SKui-Feng Lee 		perror("socket");
56539c7e67SKui-Feng Lee 		return -1;
57539c7e67SKui-Feng Lee 	}
58539c7e67SKui-Feng Lee 
59539c7e67SKui-Feng Lee 	return fd;
60539c7e67SKui-Feng Lee }
61539c7e67SKui-Feng Lee 
62539c7e67SKui-Feng Lee /* Connect to the server in a cgroup from the outside of the cgroup. */
talk_to_cgroup(int * client_fd,int * listen_fd,int * service_fd,struct cgroup_tcp_skb * skel)63539c7e67SKui-Feng Lee static int talk_to_cgroup(int *client_fd, int *listen_fd, int *service_fd,
64539c7e67SKui-Feng Lee 			  struct cgroup_tcp_skb *skel)
65539c7e67SKui-Feng Lee {
66539c7e67SKui-Feng Lee 	int err, cp;
67539c7e67SKui-Feng Lee 	char buf[5];
68*96ead1e7SKui-Feng Lee 	int port;
69539c7e67SKui-Feng Lee 
70539c7e67SKui-Feng Lee 	/* Create client & server socket */
71539c7e67SKui-Feng Lee 	err = join_root_cgroup();
72539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "join_root_cgroup"))
73539c7e67SKui-Feng Lee 		return -1;
74539c7e67SKui-Feng Lee 	*client_fd = create_client_sock_v6();
75539c7e67SKui-Feng Lee 	if (!ASSERT_GE(*client_fd, 0, "client_fd"))
76539c7e67SKui-Feng Lee 		return -1;
77539c7e67SKui-Feng Lee 	err = join_cgroup(CGROUP_TCP_SKB_PATH);
78539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "join_cgroup"))
79539c7e67SKui-Feng Lee 		return -1;
80*96ead1e7SKui-Feng Lee 	*listen_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
81539c7e67SKui-Feng Lee 	if (!ASSERT_GE(*listen_fd, 0, "listen_fd"))
82539c7e67SKui-Feng Lee 		return -1;
83*96ead1e7SKui-Feng Lee 	port = get_socket_local_port(*listen_fd);
84*96ead1e7SKui-Feng Lee 	if (!ASSERT_GE(port, 0, "get_socket_local_port"))
85*96ead1e7SKui-Feng Lee 		return -1;
86*96ead1e7SKui-Feng Lee 	skel->bss->g_sock_port = ntohs(port);
87539c7e67SKui-Feng Lee 
88539c7e67SKui-Feng Lee 	/* Connect client to server */
89*96ead1e7SKui-Feng Lee 	err = connect_fd_to_fd(*client_fd, *listen_fd, 0);
90*96ead1e7SKui-Feng Lee 	if (!ASSERT_OK(err, "connect_fd_to_fd"))
91539c7e67SKui-Feng Lee 		return -1;
92539c7e67SKui-Feng Lee 	*service_fd = accept(*listen_fd, NULL, NULL);
93539c7e67SKui-Feng Lee 	if (!ASSERT_GE(*service_fd, 0, "service_fd"))
94539c7e67SKui-Feng Lee 		return -1;
95539c7e67SKui-Feng Lee 	err = join_root_cgroup();
96539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "join_root_cgroup"))
97539c7e67SKui-Feng Lee 		return -1;
98539c7e67SKui-Feng Lee 	cp = write(*client_fd, "hello", 5);
99539c7e67SKui-Feng Lee 	if (!ASSERT_EQ(cp, 5, "write"))
100539c7e67SKui-Feng Lee 		return -1;
101539c7e67SKui-Feng Lee 	cp = read(*service_fd, buf, 5);
102539c7e67SKui-Feng Lee 	if (!ASSERT_EQ(cp, 5, "read"))
103539c7e67SKui-Feng Lee 		return -1;
104539c7e67SKui-Feng Lee 
105539c7e67SKui-Feng Lee 	return 0;
106539c7e67SKui-Feng Lee }
107539c7e67SKui-Feng Lee 
108539c7e67SKui-Feng Lee /* Connect to the server out of a cgroup from inside the cgroup. */
talk_to_outside(int * client_fd,int * listen_fd,int * service_fd,struct cgroup_tcp_skb * skel)109539c7e67SKui-Feng Lee static int talk_to_outside(int *client_fd, int *listen_fd, int *service_fd,
110539c7e67SKui-Feng Lee 			   struct cgroup_tcp_skb *skel)
111539c7e67SKui-Feng Lee 
112539c7e67SKui-Feng Lee {
113539c7e67SKui-Feng Lee 	int err, cp;
114539c7e67SKui-Feng Lee 	char buf[5];
115*96ead1e7SKui-Feng Lee 	int port;
116539c7e67SKui-Feng Lee 
117539c7e67SKui-Feng Lee 	/* Create client & server socket */
118539c7e67SKui-Feng Lee 	err = join_root_cgroup();
119539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "join_root_cgroup"))
120539c7e67SKui-Feng Lee 		return -1;
121*96ead1e7SKui-Feng Lee 	*listen_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
122539c7e67SKui-Feng Lee 	if (!ASSERT_GE(*listen_fd, 0, "listen_fd"))
123539c7e67SKui-Feng Lee 		return -1;
124539c7e67SKui-Feng Lee 	err = join_cgroup(CGROUP_TCP_SKB_PATH);
125539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "join_cgroup"))
126539c7e67SKui-Feng Lee 		return -1;
127539c7e67SKui-Feng Lee 	*client_fd = create_client_sock_v6();
128539c7e67SKui-Feng Lee 	if (!ASSERT_GE(*client_fd, 0, "client_fd"))
129539c7e67SKui-Feng Lee 		return -1;
130539c7e67SKui-Feng Lee 	err = join_root_cgroup();
131539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "join_root_cgroup"))
132539c7e67SKui-Feng Lee 		return -1;
133*96ead1e7SKui-Feng Lee 	port = get_socket_local_port(*listen_fd);
134*96ead1e7SKui-Feng Lee 	if (!ASSERT_GE(port, 0, "get_socket_local_port"))
135*96ead1e7SKui-Feng Lee 		return -1;
136*96ead1e7SKui-Feng Lee 	skel->bss->g_sock_port = ntohs(port);
137539c7e67SKui-Feng Lee 
138539c7e67SKui-Feng Lee 	/* Connect client to server */
139*96ead1e7SKui-Feng Lee 	err = connect_fd_to_fd(*client_fd, *listen_fd, 0);
140*96ead1e7SKui-Feng Lee 	if (!ASSERT_OK(err, "connect_fd_to_fd"))
141539c7e67SKui-Feng Lee 		return -1;
142539c7e67SKui-Feng Lee 	*service_fd = accept(*listen_fd, NULL, NULL);
143539c7e67SKui-Feng Lee 	if (!ASSERT_GE(*service_fd, 0, "service_fd"))
144539c7e67SKui-Feng Lee 		return -1;
145539c7e67SKui-Feng Lee 	cp = write(*client_fd, "hello", 5);
146539c7e67SKui-Feng Lee 	if (!ASSERT_EQ(cp, 5, "write"))
147539c7e67SKui-Feng Lee 		return -1;
148539c7e67SKui-Feng Lee 	cp = read(*service_fd, buf, 5);
149539c7e67SKui-Feng Lee 	if (!ASSERT_EQ(cp, 5, "read"))
150539c7e67SKui-Feng Lee 		return -1;
151539c7e67SKui-Feng Lee 
152539c7e67SKui-Feng Lee 	return 0;
153539c7e67SKui-Feng Lee }
154539c7e67SKui-Feng Lee 
close_connection(int * closing_fd,int * peer_fd,int * listen_fd,struct cgroup_tcp_skb * skel)155539c7e67SKui-Feng Lee static int close_connection(int *closing_fd, int *peer_fd, int *listen_fd,
156539c7e67SKui-Feng Lee 			    struct cgroup_tcp_skb *skel)
157539c7e67SKui-Feng Lee {
158539c7e67SKui-Feng Lee 	__u32 saved_packet_count = 0;
159539c7e67SKui-Feng Lee 	int err;
160539c7e67SKui-Feng Lee 	int i;
161539c7e67SKui-Feng Lee 
162539c7e67SKui-Feng Lee 	/* Wait for ACKs to be sent */
163539c7e67SKui-Feng Lee 	saved_packet_count = skel->bss->g_packet_count;
164539c7e67SKui-Feng Lee 	usleep(100000);		/* 0.1s */
165539c7e67SKui-Feng Lee 	for (i = 0;
166539c7e67SKui-Feng Lee 	     skel->bss->g_packet_count != saved_packet_count && i < 10;
167539c7e67SKui-Feng Lee 	     i++) {
168539c7e67SKui-Feng Lee 		saved_packet_count = skel->bss->g_packet_count;
169539c7e67SKui-Feng Lee 		usleep(100000);	/* 0.1s */
170539c7e67SKui-Feng Lee 	}
171539c7e67SKui-Feng Lee 	if (!ASSERT_EQ(skel->bss->g_packet_count, saved_packet_count,
172539c7e67SKui-Feng Lee 		       "packet_count"))
173539c7e67SKui-Feng Lee 		return -1;
174539c7e67SKui-Feng Lee 
175539c7e67SKui-Feng Lee 	skel->bss->g_packet_count = 0;
176539c7e67SKui-Feng Lee 	saved_packet_count = 0;
177539c7e67SKui-Feng Lee 
178539c7e67SKui-Feng Lee 	/* Half shutdown to make sure the closing socket having a chance to
179539c7e67SKui-Feng Lee 	 * receive a FIN from the peer.
180539c7e67SKui-Feng Lee 	 */
181539c7e67SKui-Feng Lee 	err = shutdown(*closing_fd, SHUT_WR);
182539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "shutdown closing_fd"))
183539c7e67SKui-Feng Lee 		return -1;
184539c7e67SKui-Feng Lee 
185539c7e67SKui-Feng Lee 	/* Wait for FIN and the ACK of the FIN to be observed */
186539c7e67SKui-Feng Lee 	for (i = 0;
187539c7e67SKui-Feng Lee 	     skel->bss->g_packet_count < saved_packet_count + 2 && i < 10;
188539c7e67SKui-Feng Lee 	     i++)
189539c7e67SKui-Feng Lee 		usleep(100000);	/* 0.1s */
190539c7e67SKui-Feng Lee 	if (!ASSERT_GE(skel->bss->g_packet_count, saved_packet_count + 2,
191539c7e67SKui-Feng Lee 		       "packet_count"))
192539c7e67SKui-Feng Lee 		return -1;
193539c7e67SKui-Feng Lee 
194539c7e67SKui-Feng Lee 	saved_packet_count = skel->bss->g_packet_count;
195539c7e67SKui-Feng Lee 
196539c7e67SKui-Feng Lee 	/* Fully shutdown the connection */
197539c7e67SKui-Feng Lee 	err = close(*peer_fd);
198539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "close peer_fd"))
199539c7e67SKui-Feng Lee 		return -1;
200539c7e67SKui-Feng Lee 	*peer_fd = -1;
201539c7e67SKui-Feng Lee 
202539c7e67SKui-Feng Lee 	/* Wait for FIN and the ACK of the FIN to be observed */
203539c7e67SKui-Feng Lee 	for (i = 0;
204539c7e67SKui-Feng Lee 	     skel->bss->g_packet_count < saved_packet_count + 2 && i < 10;
205539c7e67SKui-Feng Lee 	     i++)
206539c7e67SKui-Feng Lee 		usleep(100000);	/* 0.1s */
207539c7e67SKui-Feng Lee 	if (!ASSERT_GE(skel->bss->g_packet_count, saved_packet_count + 2,
208539c7e67SKui-Feng Lee 		       "packet_count"))
209539c7e67SKui-Feng Lee 		return -1;
210539c7e67SKui-Feng Lee 
211539c7e67SKui-Feng Lee 	err = close(*closing_fd);
212539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "close closing_fd"))
213539c7e67SKui-Feng Lee 		return -1;
214539c7e67SKui-Feng Lee 	*closing_fd = -1;
215539c7e67SKui-Feng Lee 
216539c7e67SKui-Feng Lee 	close(*listen_fd);
217539c7e67SKui-Feng Lee 	*listen_fd = -1;
218539c7e67SKui-Feng Lee 
219539c7e67SKui-Feng Lee 	return 0;
220539c7e67SKui-Feng Lee }
221539c7e67SKui-Feng Lee 
222539c7e67SKui-Feng Lee /* This test case includes four scenarios:
223539c7e67SKui-Feng Lee  * 1. Connect to the server from outside the cgroup and close the connection
224539c7e67SKui-Feng Lee  *    from outside the cgroup.
225539c7e67SKui-Feng Lee  * 2. Connect to the server from outside the cgroup and close the connection
226539c7e67SKui-Feng Lee  *    from inside the cgroup.
227539c7e67SKui-Feng Lee  * 3. Connect to the server from inside the cgroup and close the connection
228539c7e67SKui-Feng Lee  *    from outside the cgroup.
229539c7e67SKui-Feng Lee  * 4. Connect to the server from inside the cgroup and close the connection
230539c7e67SKui-Feng Lee  *    from inside the cgroup.
231539c7e67SKui-Feng Lee  *
232539c7e67SKui-Feng Lee  * The test case is to verify that cgroup_skb/{egress,ingress} filters
233539c7e67SKui-Feng Lee  * receive expected packets including SYN, SYN/ACK, ACK, FIN, and FIN/ACK.
234539c7e67SKui-Feng Lee  */
test_cgroup_tcp_skb(void)235539c7e67SKui-Feng Lee void test_cgroup_tcp_skb(void)
236539c7e67SKui-Feng Lee {
237539c7e67SKui-Feng Lee 	struct bpf_link *ingress_link = NULL;
238539c7e67SKui-Feng Lee 	struct bpf_link *egress_link = NULL;
239539c7e67SKui-Feng Lee 	int client_fd = -1, listen_fd = -1;
240539c7e67SKui-Feng Lee 	struct cgroup_tcp_skb *skel;
241539c7e67SKui-Feng Lee 	int service_fd = -1;
242539c7e67SKui-Feng Lee 	int cgroup_fd = -1;
243539c7e67SKui-Feng Lee 	int err;
244539c7e67SKui-Feng Lee 
245539c7e67SKui-Feng Lee 	skel = cgroup_tcp_skb__open_and_load();
246539c7e67SKui-Feng Lee 	if (!ASSERT_OK(!skel, "skel_open_load"))
247539c7e67SKui-Feng Lee 		return;
248539c7e67SKui-Feng Lee 
249539c7e67SKui-Feng Lee 	err = setup_cgroup_environment();
250539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "setup_cgroup_environment"))
251539c7e67SKui-Feng Lee 		goto cleanup;
252539c7e67SKui-Feng Lee 
253539c7e67SKui-Feng Lee 	cgroup_fd = create_and_get_cgroup(CGROUP_TCP_SKB_PATH);
254539c7e67SKui-Feng Lee 	if (!ASSERT_GE(cgroup_fd, 0, "cgroup_fd"))
255539c7e67SKui-Feng Lee 		goto cleanup;
256539c7e67SKui-Feng Lee 
257539c7e67SKui-Feng Lee 	/* Scenario 1 */
258539c7e67SKui-Feng Lee 	err = install_filters(cgroup_fd, &egress_link, &ingress_link,
259539c7e67SKui-Feng Lee 			      skel->progs.server_egress,
260539c7e67SKui-Feng Lee 			      skel->progs.server_ingress,
261539c7e67SKui-Feng Lee 			      skel);
262539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "install_filters"))
263539c7e67SKui-Feng Lee 		goto cleanup;
264539c7e67SKui-Feng Lee 
265539c7e67SKui-Feng Lee 	err = talk_to_cgroup(&client_fd, &listen_fd, &service_fd, skel);
266539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "talk_to_cgroup"))
267539c7e67SKui-Feng Lee 		goto cleanup;
268539c7e67SKui-Feng Lee 
269539c7e67SKui-Feng Lee 	err = close_connection(&client_fd, &service_fd, &listen_fd, skel);
270539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "close_connection"))
271539c7e67SKui-Feng Lee 		goto cleanup;
272539c7e67SKui-Feng Lee 
273539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected");
274539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_sock_state, CLOSED, "g_sock_state");
275539c7e67SKui-Feng Lee 
276539c7e67SKui-Feng Lee 	uninstall_filters(&egress_link, &ingress_link);
277539c7e67SKui-Feng Lee 
278539c7e67SKui-Feng Lee 	/* Scenario 2 */
279539c7e67SKui-Feng Lee 	err = install_filters(cgroup_fd, &egress_link, &ingress_link,
280539c7e67SKui-Feng Lee 			      skel->progs.server_egress_srv,
281539c7e67SKui-Feng Lee 			      skel->progs.server_ingress_srv,
282539c7e67SKui-Feng Lee 			      skel);
283539c7e67SKui-Feng Lee 
284539c7e67SKui-Feng Lee 	err = talk_to_cgroup(&client_fd, &listen_fd, &service_fd, skel);
285539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "talk_to_cgroup"))
286539c7e67SKui-Feng Lee 		goto cleanup;
287539c7e67SKui-Feng Lee 
288539c7e67SKui-Feng Lee 	err = close_connection(&service_fd, &client_fd, &listen_fd, skel);
289539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "close_connection"))
290539c7e67SKui-Feng Lee 		goto cleanup;
291539c7e67SKui-Feng Lee 
292539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected");
293539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_sock_state, TIME_WAIT, "g_sock_state");
294539c7e67SKui-Feng Lee 
295539c7e67SKui-Feng Lee 	uninstall_filters(&egress_link, &ingress_link);
296539c7e67SKui-Feng Lee 
297539c7e67SKui-Feng Lee 	/* Scenario 3 */
298539c7e67SKui-Feng Lee 	err = install_filters(cgroup_fd, &egress_link, &ingress_link,
299539c7e67SKui-Feng Lee 			      skel->progs.client_egress_srv,
300539c7e67SKui-Feng Lee 			      skel->progs.client_ingress_srv,
301539c7e67SKui-Feng Lee 			      skel);
302539c7e67SKui-Feng Lee 
303539c7e67SKui-Feng Lee 	err = talk_to_outside(&client_fd, &listen_fd, &service_fd, skel);
304539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "talk_to_outside"))
305539c7e67SKui-Feng Lee 		goto cleanup;
306539c7e67SKui-Feng Lee 
307539c7e67SKui-Feng Lee 	err = close_connection(&service_fd, &client_fd, &listen_fd, skel);
308539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "close_connection"))
309539c7e67SKui-Feng Lee 		goto cleanup;
310539c7e67SKui-Feng Lee 
311539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected");
312539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_sock_state, CLOSED, "g_sock_state");
313539c7e67SKui-Feng Lee 
314539c7e67SKui-Feng Lee 	uninstall_filters(&egress_link, &ingress_link);
315539c7e67SKui-Feng Lee 
316539c7e67SKui-Feng Lee 	/* Scenario 4 */
317539c7e67SKui-Feng Lee 	err = install_filters(cgroup_fd, &egress_link, &ingress_link,
318539c7e67SKui-Feng Lee 			      skel->progs.client_egress,
319539c7e67SKui-Feng Lee 			      skel->progs.client_ingress,
320539c7e67SKui-Feng Lee 			      skel);
321539c7e67SKui-Feng Lee 
322539c7e67SKui-Feng Lee 	err = talk_to_outside(&client_fd, &listen_fd, &service_fd, skel);
323539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "talk_to_outside"))
324539c7e67SKui-Feng Lee 		goto cleanup;
325539c7e67SKui-Feng Lee 
326539c7e67SKui-Feng Lee 	err = close_connection(&client_fd, &service_fd, &listen_fd, skel);
327539c7e67SKui-Feng Lee 	if (!ASSERT_OK(err, "close_connection"))
328539c7e67SKui-Feng Lee 		goto cleanup;
329539c7e67SKui-Feng Lee 
330539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_unexpected, 0, "g_unexpected");
331539c7e67SKui-Feng Lee 	ASSERT_EQ(skel->bss->g_sock_state, TIME_WAIT, "g_sock_state");
332539c7e67SKui-Feng Lee 
333539c7e67SKui-Feng Lee 	uninstall_filters(&egress_link, &ingress_link);
334539c7e67SKui-Feng Lee 
335539c7e67SKui-Feng Lee cleanup:
336539c7e67SKui-Feng Lee 	close(client_fd);
337539c7e67SKui-Feng Lee 	close(listen_fd);
338539c7e67SKui-Feng Lee 	close(service_fd);
339539c7e67SKui-Feng Lee 	close(cgroup_fd);
340539c7e67SKui-Feng Lee 	bpf_link__destroy(egress_link);
341539c7e67SKui-Feng Lee 	bpf_link__destroy(ingress_link);
342539c7e67SKui-Feng Lee 	cleanup_cgroup_environment();
343539c7e67SKui-Feng Lee 	cgroup_tcp_skb__destroy(skel);
344539c7e67SKui-Feng Lee }
345