Linux Audio

Check our new training course

Loading...
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <test_progs.h>
  4#include "cgroup_helpers.h"
  5#include "network_helpers.h"
  6
  7static int verify_ports(int family, int fd,
  8			__u16 expected_local, __u16 expected_peer)
  9{
 10	struct sockaddr_storage addr;
 11	socklen_t len = sizeof(addr);
 12	__u16 port;
 13
 14	if (getsockname(fd, (struct sockaddr *)&addr, &len)) {
 15		log_err("Failed to get server addr");
 16		return -1;
 17	}
 18
 19	if (family == AF_INET)
 20		port = ((struct sockaddr_in *)&addr)->sin_port;
 21	else
 22		port = ((struct sockaddr_in6 *)&addr)->sin6_port;
 23
 24	if (ntohs(port) != expected_local) {
 25		log_err("Unexpected local port %d, expected %d", ntohs(port),
 26			expected_local);
 27		return -1;
 28	}
 29
 30	if (getpeername(fd, (struct sockaddr *)&addr, &len)) {
 31		log_err("Failed to get peer addr");
 32		return -1;
 33	}
 34
 35	if (family == AF_INET)
 36		port = ((struct sockaddr_in *)&addr)->sin_port;
 37	else
 38		port = ((struct sockaddr_in6 *)&addr)->sin6_port;
 39
 40	if (ntohs(port) != expected_peer) {
 41		log_err("Unexpected peer port %d, expected %d", ntohs(port),
 42			expected_peer);
 43		return -1;
 44	}
 45
 46	return 0;
 47}
 48
 49static int run_test(int cgroup_fd, int server_fd, int family, int type)
 50{
 51	bool v4 = family == AF_INET;
 52	__u16 expected_local_port = v4 ? 22222 : 22223;
 53	__u16 expected_peer_port = 60000;
 54	struct bpf_program *prog;
 55	struct bpf_object *obj;
 56	const char *obj_file = v4 ? "connect_force_port4.bpf.o" : "connect_force_port6.bpf.o";
 57	int fd, err;
 58	__u32 duration = 0;
 59
 60	obj = bpf_object__open_file(obj_file, NULL);
 61	if (!ASSERT_OK_PTR(obj, "bpf_obj_open"))
 62		return -1;
 63
 64	err = bpf_object__load(obj);
 65	if (!ASSERT_OK(err, "bpf_obj_load")) {
 66		err = -EIO;
 67		goto close_bpf_object;
 68	}
 69
 70	prog = bpf_object__find_program_by_name(obj, v4 ?
 71						"connect4" :
 72						"connect6");
 73	if (CHECK(!prog, "find_prog", "connect prog not found\n")) {
 74		err = -EIO;
 75		goto close_bpf_object;
 76	}
 77
 78	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
 79			      BPF_CGROUP_INET4_CONNECT :
 80			      BPF_CGROUP_INET6_CONNECT, 0);
 81	if (err) {
 82		log_err("Failed to attach BPF program");
 83		goto close_bpf_object;
 84	}
 85
 86	prog = bpf_object__find_program_by_name(obj, v4 ?
 87						"getpeername4" :
 88						"getpeername6");
 89	if (CHECK(!prog, "find_prog", "getpeername prog not found\n")) {
 90		err = -EIO;
 91		goto close_bpf_object;
 92	}
 93
 94	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
 95			      BPF_CGROUP_INET4_GETPEERNAME :
 96			      BPF_CGROUP_INET6_GETPEERNAME, 0);
 97	if (err) {
 98		log_err("Failed to attach BPF program");
 99		goto close_bpf_object;
100	}
101
102	prog = bpf_object__find_program_by_name(obj, v4 ?
103						"getsockname4" :
104						"getsockname6");
105	if (CHECK(!prog, "find_prog", "getsockname prog not found\n")) {
106		err = -EIO;
107		goto close_bpf_object;
108	}
109
110	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
111			      BPF_CGROUP_INET4_GETSOCKNAME :
112			      BPF_CGROUP_INET6_GETSOCKNAME, 0);
113	if (err) {
114		log_err("Failed to attach BPF program");
115		goto close_bpf_object;
116	}
117
118	fd = connect_to_fd(server_fd, 0);
119	if (fd < 0) {
120		err = -1;
121		goto close_bpf_object;
122	}
123
124	err = verify_ports(family, fd, expected_local_port,
125			   expected_peer_port);
126	close(fd);
127
128close_bpf_object:
129	bpf_object__close(obj);
130	return err;
131}
132
133void test_connect_force_port(void)
134{
135	int server_fd, cgroup_fd;
136
137	cgroup_fd = test__join_cgroup("/connect_force_port");
138	if (CHECK_FAIL(cgroup_fd < 0))
139		return;
140
141	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 60123, 0);
142	if (CHECK_FAIL(server_fd < 0))
143		goto close_cgroup_fd;
144	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET, SOCK_STREAM));
145	close(server_fd);
146
147	server_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 60124, 0);
148	if (CHECK_FAIL(server_fd < 0))
149		goto close_cgroup_fd;
150	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET6, SOCK_STREAM));
151	close(server_fd);
152
153	server_fd = start_server(AF_INET, SOCK_DGRAM, NULL, 60123, 0);
154	if (CHECK_FAIL(server_fd < 0))
155		goto close_cgroup_fd;
156	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET, SOCK_DGRAM));
157	close(server_fd);
158
159	server_fd = start_server(AF_INET6, SOCK_DGRAM, NULL, 60124, 0);
160	if (CHECK_FAIL(server_fd < 0))
161		goto close_cgroup_fd;
162	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET6, SOCK_DGRAM));
163	close(server_fd);
164
165close_cgroup_fd:
166	close(cgroup_fd);
167}