1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <test_progs.h>
4 
5 #include "connect4_dropper.skel.h"
6 
7 #include "cgroup_helpers.h"
8 #include "network_helpers.h"
9 
run_test(int cgroup_fd,int server_fd,bool classid)10 static int run_test(int cgroup_fd, int server_fd, bool classid)
11 {
12 	struct connect4_dropper *skel;
13 	int fd, err = 0, port;
14 
15 	skel = connect4_dropper__open_and_load();
16 	if (!ASSERT_OK_PTR(skel, "skel_open"))
17 		return -1;
18 
19 	port = get_socket_local_port(server_fd);
20 	if (!ASSERT_GE(port, 0, "get_socket_local_port"))
21 		return -1;
22 
23 	skel->bss->port = ntohs(port);
24 
25 	skel->links.connect_v4_dropper =
26 		bpf_program__attach_cgroup(skel->progs.connect_v4_dropper,
27 					   cgroup_fd);
28 	if (!ASSERT_OK_PTR(skel->links.connect_v4_dropper, "prog_attach")) {
29 		err = -1;
30 		goto out;
31 	}
32 
33 	if (classid && !ASSERT_OK(join_classid(), "join_classid")) {
34 		err = -1;
35 		goto out;
36 	}
37 
38 	errno = 0;
39 	fd = connect_to_fd_opts(server_fd, NULL);
40 	if (fd >= 0) {
41 		log_err("Unexpected success to connect to server");
42 		err = -1;
43 		close(fd);
44 	} else if (errno != EPERM) {
45 		log_err("Unexpected errno from connect to server");
46 		err = -1;
47 	}
48 out:
49 	connect4_dropper__destroy(skel);
50 	return err;
51 }
52 
test_cgroup_v1v2(void)53 void test_cgroup_v1v2(void)
54 {
55 	struct network_helper_opts opts = {};
56 	int server_fd, client_fd, cgroup_fd;
57 
58 	/* Step 1: Check base connectivity works without any BPF. */
59 	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
60 	if (!ASSERT_GE(server_fd, 0, "server_fd"))
61 		return;
62 	client_fd = connect_to_fd_opts(server_fd, &opts);
63 	if (!ASSERT_GE(client_fd, 0, "client_fd")) {
64 		close(server_fd);
65 		return;
66 	}
67 	close(client_fd);
68 	close(server_fd);
69 
70 	/* Step 2: Check BPF policy prog attached to cgroups drops connectivity. */
71 	cgroup_fd = test__join_cgroup("/connect_dropper");
72 	if (!ASSERT_GE(cgroup_fd, 0, "cgroup_fd"))
73 		return;
74 	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
75 	if (!ASSERT_GE(server_fd, 0, "server_fd")) {
76 		close(cgroup_fd);
77 		return;
78 	}
79 	ASSERT_OK(run_test(cgroup_fd, server_fd, false), "cgroup-v2-only");
80 	setup_classid_environment();
81 	set_classid();
82 	ASSERT_OK(run_test(cgroup_fd, server_fd, true), "cgroup-v1v2");
83 	cleanup_classid_environment();
84 	close(server_fd);
85 	close(cgroup_fd);
86 }
87