connect_force_port.c (4198B)
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.o" : "connect_force_port6.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}