Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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