0001
0002
0003 #include <test_progs.h>
0004 #include "cgroup_helpers.h"
0005 #include "network_helpers.h"
0006
0007 static int verify_ports(int family, int fd,
0008 __u16 expected_local, __u16 expected_peer)
0009 {
0010 struct sockaddr_storage addr;
0011 socklen_t len = sizeof(addr);
0012 __u16 port;
0013
0014 if (getsockname(fd, (struct sockaddr *)&addr, &len)) {
0015 log_err("Failed to get server addr");
0016 return -1;
0017 }
0018
0019 if (family == AF_INET)
0020 port = ((struct sockaddr_in *)&addr)->sin_port;
0021 else
0022 port = ((struct sockaddr_in6 *)&addr)->sin6_port;
0023
0024 if (ntohs(port) != expected_local) {
0025 log_err("Unexpected local port %d, expected %d", ntohs(port),
0026 expected_local);
0027 return -1;
0028 }
0029
0030 if (getpeername(fd, (struct sockaddr *)&addr, &len)) {
0031 log_err("Failed to get peer addr");
0032 return -1;
0033 }
0034
0035 if (family == AF_INET)
0036 port = ((struct sockaddr_in *)&addr)->sin_port;
0037 else
0038 port = ((struct sockaddr_in6 *)&addr)->sin6_port;
0039
0040 if (ntohs(port) != expected_peer) {
0041 log_err("Unexpected peer port %d, expected %d", ntohs(port),
0042 expected_peer);
0043 return -1;
0044 }
0045
0046 return 0;
0047 }
0048
0049 static int run_test(int cgroup_fd, int server_fd, int family, int type)
0050 {
0051 bool v4 = family == AF_INET;
0052 __u16 expected_local_port = v4 ? 22222 : 22223;
0053 __u16 expected_peer_port = 60000;
0054 struct bpf_program *prog;
0055 struct bpf_object *obj;
0056 const char *obj_file = v4 ? "connect_force_port4.o" : "connect_force_port6.o";
0057 int fd, err;
0058 __u32 duration = 0;
0059
0060 obj = bpf_object__open_file(obj_file, NULL);
0061 if (!ASSERT_OK_PTR(obj, "bpf_obj_open"))
0062 return -1;
0063
0064 err = bpf_object__load(obj);
0065 if (!ASSERT_OK(err, "bpf_obj_load")) {
0066 err = -EIO;
0067 goto close_bpf_object;
0068 }
0069
0070 prog = bpf_object__find_program_by_name(obj, v4 ?
0071 "connect4" :
0072 "connect6");
0073 if (CHECK(!prog, "find_prog", "connect prog not found\n")) {
0074 err = -EIO;
0075 goto close_bpf_object;
0076 }
0077
0078 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
0079 BPF_CGROUP_INET4_CONNECT :
0080 BPF_CGROUP_INET6_CONNECT, 0);
0081 if (err) {
0082 log_err("Failed to attach BPF program");
0083 goto close_bpf_object;
0084 }
0085
0086 prog = bpf_object__find_program_by_name(obj, v4 ?
0087 "getpeername4" :
0088 "getpeername6");
0089 if (CHECK(!prog, "find_prog", "getpeername prog not found\n")) {
0090 err = -EIO;
0091 goto close_bpf_object;
0092 }
0093
0094 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
0095 BPF_CGROUP_INET4_GETPEERNAME :
0096 BPF_CGROUP_INET6_GETPEERNAME, 0);
0097 if (err) {
0098 log_err("Failed to attach BPF program");
0099 goto close_bpf_object;
0100 }
0101
0102 prog = bpf_object__find_program_by_name(obj, v4 ?
0103 "getsockname4" :
0104 "getsockname6");
0105 if (CHECK(!prog, "find_prog", "getsockname prog not found\n")) {
0106 err = -EIO;
0107 goto close_bpf_object;
0108 }
0109
0110 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
0111 BPF_CGROUP_INET4_GETSOCKNAME :
0112 BPF_CGROUP_INET6_GETSOCKNAME, 0);
0113 if (err) {
0114 log_err("Failed to attach BPF program");
0115 goto close_bpf_object;
0116 }
0117
0118 fd = connect_to_fd(server_fd, 0);
0119 if (fd < 0) {
0120 err = -1;
0121 goto close_bpf_object;
0122 }
0123
0124 err = verify_ports(family, fd, expected_local_port,
0125 expected_peer_port);
0126 close(fd);
0127
0128 close_bpf_object:
0129 bpf_object__close(obj);
0130 return err;
0131 }
0132
0133 void test_connect_force_port(void)
0134 {
0135 int server_fd, cgroup_fd;
0136
0137 cgroup_fd = test__join_cgroup("/connect_force_port");
0138 if (CHECK_FAIL(cgroup_fd < 0))
0139 return;
0140
0141 server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 60123, 0);
0142 if (CHECK_FAIL(server_fd < 0))
0143 goto close_cgroup_fd;
0144 CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET, SOCK_STREAM));
0145 close(server_fd);
0146
0147 server_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 60124, 0);
0148 if (CHECK_FAIL(server_fd < 0))
0149 goto close_cgroup_fd;
0150 CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET6, SOCK_STREAM));
0151 close(server_fd);
0152
0153 server_fd = start_server(AF_INET, SOCK_DGRAM, NULL, 60123, 0);
0154 if (CHECK_FAIL(server_fd < 0))
0155 goto close_cgroup_fd;
0156 CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET, SOCK_DGRAM));
0157 close(server_fd);
0158
0159 server_fd = start_server(AF_INET6, SOCK_DGRAM, NULL, 60124, 0);
0160 if (CHECK_FAIL(server_fd < 0))
0161 goto close_cgroup_fd;
0162 CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET6, SOCK_DGRAM));
0163 close(server_fd);
0164
0165 close_cgroup_fd:
0166 close(cgroup_fd);
0167 }