1 // SPDX-License-Identifier: GPL-2.0-only 2 #define _GNU_SOURCE 3 4 #include <errno.h> 5 #include <stdbool.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <unistd.h> 9 #include <sched.h> 10 11 #include <arpa/inet.h> 12 #include <sys/mount.h> 13 #include <sys/stat.h> 14 15 #include <linux/err.h> 16 #include <linux/in.h> 17 #include <linux/in6.h> 18 #include <linux/limits.h> 19 20 #include "bpf_util.h" 21 #include "network_helpers.h" 22 #include "test_progs.h" 23 24 #ifndef IPPROTO_MPTCP 25 #define IPPROTO_MPTCP 262 26 #endif 27 28 #define clean_errno() (errno == 0 ? "None" : strerror(errno)) 29 #define log_err(MSG, ...) ({ \ 30 int __save = errno; \ 31 fprintf(stderr, "(%s:%d: errno: %s) " MSG "\n", \ 32 __FILE__, __LINE__, clean_errno(), \ 33 ##__VA_ARGS__); \ 34 errno = __save; \ 35 }) 36 37 struct ipv4_packet pkt_v4 = { 38 .eth.h_proto = __bpf_constant_htons(ETH_P_IP), 39 .iph.ihl = 5, 40 .iph.protocol = IPPROTO_TCP, 41 .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), 42 .tcp.urg_ptr = 123, 43 .tcp.doff = 5, 44 }; 45 46 struct ipv6_packet pkt_v6 = { 47 .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), 48 .iph.nexthdr = IPPROTO_TCP, 49 .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), 50 .tcp.urg_ptr = 123, 51 .tcp.doff = 5, 52 }; 53 54 int settimeo(int fd, int timeout_ms) 55 { 56 struct timeval timeout = { .tv_sec = 3 }; 57 58 if (timeout_ms > 0) { 59 timeout.tv_sec = timeout_ms / 1000; 60 timeout.tv_usec = (timeout_ms % 1000) * 1000; 61 } 62 63 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, 64 sizeof(timeout))) { 65 log_err("Failed to set SO_RCVTIMEO"); 66 return -1; 67 } 68 69 if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, 70 sizeof(timeout))) { 71 log_err("Failed to set SO_SNDTIMEO"); 72 return -1; 73 } 74 75 return 0; 76 } 77 78 #define save_errno_close(fd) ({ int __save = errno; close(fd); errno = __save; }) 79 80 static int __start_server(int type, int protocol, const struct sockaddr *addr, 81 socklen_t addrlen, int timeout_ms, bool reuseport) 82 { 83 int on = 1; 84 int fd; 85 86 fd = socket(addr->sa_family, type, protocol); 87 if (fd < 0) { 88 log_err("Failed to create server socket"); 89 return -1; 90 } 91 92 if (settimeo(fd, timeout_ms)) 93 goto error_close; 94 95 if (reuseport && 96 setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) { 97 log_err("Failed to set SO_REUSEPORT"); 98 goto error_close; 99 } 100 101 if (bind(fd, addr, addrlen) < 0) { 102 log_err("Failed to bind socket"); 103 goto error_close; 104 } 105 106 if (type == SOCK_STREAM) { 107 if (listen(fd, 1) < 0) { 108 log_err("Failed to listed on socket"); 109 goto error_close; 110 } 111 } 112 113 return fd; 114 115 error_close: 116 save_errno_close(fd); 117 return -1; 118 } 119 120 static int start_server_proto(int family, int type, int protocol, 121 const char *addr_str, __u16 port, int timeout_ms) 122 { 123 struct sockaddr_storage addr; 124 socklen_t addrlen; 125 126 if (make_sockaddr(family, addr_str, port, &addr, &addrlen)) 127 return -1; 128 129 return __start_server(type, protocol, (struct sockaddr *)&addr, 130 addrlen, timeout_ms, false); 131 } 132 133 int start_server(int family, int type, const char *addr_str, __u16 port, 134 int timeout_ms) 135 { 136 return start_server_proto(family, type, 0, addr_str, port, timeout_ms); 137 } 138 139 int start_mptcp_server(int family, const char *addr_str, __u16 port, 140 int timeout_ms) 141 { 142 return start_server_proto(family, SOCK_STREAM, IPPROTO_MPTCP, addr_str, 143 port, timeout_ms); 144 } 145 146 int *start_reuseport_server(int family, int type, const char *addr_str, 147 __u16 port, int timeout_ms, unsigned int nr_listens) 148 { 149 struct sockaddr_storage addr; 150 unsigned int nr_fds = 0; 151 socklen_t addrlen; 152 int *fds; 153 154 if (!nr_listens) 155 return NULL; 156 157 if (make_sockaddr(family, addr_str, port, &addr, &addrlen)) 158 return NULL; 159 160 fds = malloc(sizeof(*fds) * nr_listens); 161 if (!fds) 162 return NULL; 163 164 fds[0] = __start_server(type, 0, (struct sockaddr *)&addr, addrlen, 165 timeout_ms, true); 166 if (fds[0] == -1) 167 goto close_fds; 168 nr_fds = 1; 169 170 if (getsockname(fds[0], (struct sockaddr *)&addr, &addrlen)) 171 goto close_fds; 172 173 for (; nr_fds < nr_listens; nr_fds++) { 174 fds[nr_fds] = __start_server(type, 0, (struct sockaddr *)&addr, 175 addrlen, timeout_ms, true); 176 if (fds[nr_fds] == -1) 177 goto close_fds; 178 } 179 180 return fds; 181 182 close_fds: 183 free_fds(fds, nr_fds); 184 return NULL; 185 } 186 187 void free_fds(int *fds, unsigned int nr_close_fds) 188 { 189 if (fds) { 190 while (nr_close_fds) 191 close(fds[--nr_close_fds]); 192 free(fds); 193 } 194 } 195 196 int fastopen_connect(int server_fd, const char *data, unsigned int data_len, 197 int timeout_ms) 198 { 199 struct sockaddr_storage addr; 200 socklen_t addrlen = sizeof(addr); 201 struct sockaddr_in *addr_in; 202 int fd, ret; 203 204 if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) { 205 log_err("Failed to get server addr"); 206 return -1; 207 } 208 209 addr_in = (struct sockaddr_in *)&addr; 210 fd = socket(addr_in->sin_family, SOCK_STREAM, 0); 211 if (fd < 0) { 212 log_err("Failed to create client socket"); 213 return -1; 214 } 215 216 if (settimeo(fd, timeout_ms)) 217 goto error_close; 218 219 ret = sendto(fd, data, data_len, MSG_FASTOPEN, (struct sockaddr *)&addr, 220 addrlen); 221 if (ret != data_len) { 222 log_err("sendto(data, %u) != %d\n", data_len, ret); 223 goto error_close; 224 } 225 226 return fd; 227 228 error_close: 229 save_errno_close(fd); 230 return -1; 231 } 232 233 static int connect_fd_to_addr(int fd, 234 const struct sockaddr_storage *addr, 235 socklen_t addrlen, const bool must_fail) 236 { 237 int ret; 238 239 errno = 0; 240 ret = connect(fd, (const struct sockaddr *)addr, addrlen); 241 if (must_fail) { 242 if (!ret) { 243 log_err("Unexpected success to connect to server"); 244 return -1; 245 } 246 if (errno != EPERM) { 247 log_err("Unexpected error from connect to server"); 248 return -1; 249 } 250 } else { 251 if (ret) { 252 log_err("Failed to connect to server"); 253 return -1; 254 } 255 } 256 257 return 0; 258 } 259 260 static const struct network_helper_opts default_opts; 261 262 int connect_to_fd_opts(int server_fd, const struct network_helper_opts *opts) 263 { 264 struct sockaddr_storage addr; 265 struct sockaddr_in *addr_in; 266 socklen_t addrlen, optlen; 267 int fd, type, protocol; 268 269 if (!opts) 270 opts = &default_opts; 271 272 optlen = sizeof(type); 273 274 if (opts->type) { 275 type = opts->type; 276 } else { 277 if (getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &type, &optlen)) { 278 log_err("getsockopt(SOL_TYPE)"); 279 return -1; 280 } 281 } 282 283 if (opts->proto) { 284 protocol = opts->proto; 285 } else { 286 if (getsockopt(server_fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen)) { 287 log_err("getsockopt(SOL_PROTOCOL)"); 288 return -1; 289 } 290 } 291 292 addrlen = sizeof(addr); 293 if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) { 294 log_err("Failed to get server addr"); 295 return -1; 296 } 297 298 addr_in = (struct sockaddr_in *)&addr; 299 fd = socket(addr_in->sin_family, type, protocol); 300 if (fd < 0) { 301 log_err("Failed to create client socket"); 302 return -1; 303 } 304 305 if (settimeo(fd, opts->timeout_ms)) 306 goto error_close; 307 308 if (opts->cc && opts->cc[0] && 309 setsockopt(fd, SOL_TCP, TCP_CONGESTION, opts->cc, 310 strlen(opts->cc) + 1)) 311 goto error_close; 312 313 if (!opts->noconnect) 314 if (connect_fd_to_addr(fd, &addr, addrlen, opts->must_fail)) 315 goto error_close; 316 317 return fd; 318 319 error_close: 320 save_errno_close(fd); 321 return -1; 322 } 323 324 int connect_to_fd(int server_fd, int timeout_ms) 325 { 326 struct network_helper_opts opts = { 327 .timeout_ms = timeout_ms, 328 }; 329 330 return connect_to_fd_opts(server_fd, &opts); 331 } 332 333 int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms) 334 { 335 struct sockaddr_storage addr; 336 socklen_t len = sizeof(addr); 337 338 if (settimeo(client_fd, timeout_ms)) 339 return -1; 340 341 if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { 342 log_err("Failed to get server addr"); 343 return -1; 344 } 345 346 if (connect_fd_to_addr(client_fd, &addr, len, false)) 347 return -1; 348 349 return 0; 350 } 351 352 int make_sockaddr(int family, const char *addr_str, __u16 port, 353 struct sockaddr_storage *addr, socklen_t *len) 354 { 355 if (family == AF_INET) { 356 struct sockaddr_in *sin = (void *)addr; 357 358 memset(addr, 0, sizeof(*sin)); 359 sin->sin_family = AF_INET; 360 sin->sin_port = htons(port); 361 if (addr_str && 362 inet_pton(AF_INET, addr_str, &sin->sin_addr) != 1) { 363 log_err("inet_pton(AF_INET, %s)", addr_str); 364 return -1; 365 } 366 if (len) 367 *len = sizeof(*sin); 368 return 0; 369 } else if (family == AF_INET6) { 370 struct sockaddr_in6 *sin6 = (void *)addr; 371 372 memset(addr, 0, sizeof(*sin6)); 373 sin6->sin6_family = AF_INET6; 374 sin6->sin6_port = htons(port); 375 if (addr_str && 376 inet_pton(AF_INET6, addr_str, &sin6->sin6_addr) != 1) { 377 log_err("inet_pton(AF_INET6, %s)", addr_str); 378 return -1; 379 } 380 if (len) 381 *len = sizeof(*sin6); 382 return 0; 383 } 384 return -1; 385 } 386 387 char *ping_command(int family) 388 { 389 if (family == AF_INET6) { 390 /* On some systems 'ping' doesn't support IPv6, so use ping6 if it is present. */ 391 if (!system("which ping6 >/dev/null 2>&1")) 392 return "ping6"; 393 else 394 return "ping -6"; 395 } 396 return "ping"; 397 } 398 399 struct nstoken { 400 int orig_netns_fd; 401 }; 402 403 struct nstoken *open_netns(const char *name) 404 { 405 int nsfd; 406 char nspath[PATH_MAX]; 407 int err; 408 struct nstoken *token; 409 410 token = calloc(1, sizeof(struct nstoken)); 411 if (!ASSERT_OK_PTR(token, "malloc token")) 412 return NULL; 413 414 token->orig_netns_fd = open("/proc/self/ns/net", O_RDONLY); 415 if (!ASSERT_GE(token->orig_netns_fd, 0, "open /proc/self/ns/net")) 416 goto fail; 417 418 snprintf(nspath, sizeof(nspath), "%s/%s", "/var/run/netns", name); 419 nsfd = open(nspath, O_RDONLY | O_CLOEXEC); 420 if (!ASSERT_GE(nsfd, 0, "open netns fd")) 421 goto fail; 422 423 err = setns(nsfd, CLONE_NEWNET); 424 close(nsfd); 425 if (!ASSERT_OK(err, "setns")) 426 goto fail; 427 428 return token; 429 fail: 430 if (token->orig_netns_fd != -1) 431 close(token->orig_netns_fd); 432 free(token); 433 return NULL; 434 } 435 436 void close_netns(struct nstoken *token) 437 { 438 if (!token) 439 return; 440 441 ASSERT_OK(setns(token->orig_netns_fd, CLONE_NEWNET), "setns"); 442 close(token->orig_netns_fd); 443 free(token); 444 } 445 446 int get_socket_local_port(int sock_fd) 447 { 448 struct sockaddr_storage addr; 449 socklen_t addrlen = sizeof(addr); 450 int err; 451 452 err = getsockname(sock_fd, (struct sockaddr *)&addr, &addrlen); 453 if (err < 0) 454 return err; 455 456 if (addr.ss_family == AF_INET) { 457 struct sockaddr_in *sin = (struct sockaddr_in *)&addr; 458 459 return sin->sin_port; 460 } else if (addr.ss_family == AF_INET6) { 461 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&addr; 462 463 return sin->sin6_port; 464 } 465 466 return -1; 467 } 468