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 #include <sys/un.h> 15 16 #include <linux/err.h> 17 #include <linux/in.h> 18 #include <linux/in6.h> 19 #include <linux/limits.h> 20 21 #include "bpf_util.h" 22 #include "network_helpers.h" 23 #include "test_progs.h" 24 25 #ifndef IPPROTO_MPTCP 26 #define IPPROTO_MPTCP 262 27 #endif 28 29 #define clean_errno() (errno == 0 ? "None" : strerror(errno)) 30 #define log_err(MSG, ...) ({ \ 31 int __save = errno; \ 32 fprintf(stderr, "(%s:%d: errno: %s) " MSG "\n", \ 33 __FILE__, __LINE__, clean_errno(), \ 34 ##__VA_ARGS__); \ 35 errno = __save; \ 36 }) 37 38 struct ipv4_packet pkt_v4 = { 39 .eth.h_proto = __bpf_constant_htons(ETH_P_IP), 40 .iph.ihl = 5, 41 .iph.protocol = IPPROTO_TCP, 42 .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), 43 .tcp.urg_ptr = 123, 44 .tcp.doff = 5, 45 }; 46 47 struct ipv6_packet pkt_v6 = { 48 .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), 49 .iph.nexthdr = IPPROTO_TCP, 50 .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), 51 .tcp.urg_ptr = 123, 52 .tcp.doff = 5, 53 }; 54 55 static const struct network_helper_opts default_opts; 56 57 int settimeo(int fd, int timeout_ms) 58 { 59 struct timeval timeout = { .tv_sec = 3 }; 60 61 if (timeout_ms > 0) { 62 timeout.tv_sec = timeout_ms / 1000; 63 timeout.tv_usec = (timeout_ms % 1000) * 1000; 64 } 65 66 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, 67 sizeof(timeout))) { 68 log_err("Failed to set SO_RCVTIMEO"); 69 return -1; 70 } 71 72 if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, 73 sizeof(timeout))) { 74 log_err("Failed to set SO_SNDTIMEO"); 75 return -1; 76 } 77 78 return 0; 79 } 80 81 #define save_errno_close(fd) ({ int __save = errno; close(fd); errno = __save; }) 82 83 static int __start_server(int type, const struct sockaddr *addr, socklen_t addrlen, 84 const struct network_helper_opts *opts) 85 { 86 int fd; 87 88 fd = socket(addr->sa_family, type, opts->proto); 89 if (fd < 0) { 90 log_err("Failed to create server socket"); 91 return -1; 92 } 93 94 if (settimeo(fd, opts->timeout_ms)) 95 goto error_close; 96 97 if (opts->post_socket_cb && opts->post_socket_cb(fd, NULL)) { 98 log_err("Failed to call post_socket_cb"); 99 goto error_close; 100 } 101 102 if (bind(fd, addr, addrlen) < 0) { 103 log_err("Failed to bind socket"); 104 goto error_close; 105 } 106 107 if (type == SOCK_STREAM) { 108 if (listen(fd, 1) < 0) { 109 log_err("Failed to listed on socket"); 110 goto error_close; 111 } 112 } 113 114 return fd; 115 116 error_close: 117 save_errno_close(fd); 118 return -1; 119 } 120 121 int start_server(int family, int type, const char *addr_str, __u16 port, 122 int timeout_ms) 123 { 124 struct network_helper_opts opts = { 125 .timeout_ms = timeout_ms, 126 }; 127 struct sockaddr_storage addr; 128 socklen_t addrlen; 129 130 if (make_sockaddr(family, addr_str, port, &addr, &addrlen)) 131 return -1; 132 133 return __start_server(type, (struct sockaddr *)&addr, addrlen, &opts); 134 } 135 136 static int reuseport_cb(int fd, const struct post_socket_opts *opts) 137 { 138 int on = 1; 139 140 return setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)); 141 } 142 143 int *start_reuseport_server(int family, int type, const char *addr_str, 144 __u16 port, int timeout_ms, unsigned int nr_listens) 145 { 146 struct network_helper_opts opts = { 147 .timeout_ms = timeout_ms, 148 .post_socket_cb = reuseport_cb, 149 }; 150 struct sockaddr_storage addr; 151 unsigned int nr_fds = 0; 152 socklen_t addrlen; 153 int *fds; 154 155 if (!nr_listens) 156 return NULL; 157 158 if (make_sockaddr(family, addr_str, port, &addr, &addrlen)) 159 return NULL; 160 161 fds = malloc(sizeof(*fds) * nr_listens); 162 if (!fds) 163 return NULL; 164 165 fds[0] = __start_server(type, (struct sockaddr *)&addr, addrlen, &opts); 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, (struct sockaddr *)&addr, addrlen, &opts); 175 if (fds[nr_fds] == -1) 176 goto close_fds; 177 } 178 179 return fds; 180 181 close_fds: 182 free_fds(fds, nr_fds); 183 return NULL; 184 } 185 186 int start_server_addr(int type, const struct sockaddr_storage *addr, socklen_t len, 187 const struct network_helper_opts *opts) 188 { 189 if (!opts) 190 opts = &default_opts; 191 192 return __start_server(type, (struct sockaddr *)addr, len, opts); 193 } 194 195 void free_fds(int *fds, unsigned int nr_close_fds) 196 { 197 if (fds) { 198 while (nr_close_fds) 199 close(fds[--nr_close_fds]); 200 free(fds); 201 } 202 } 203 204 int fastopen_connect(int server_fd, const char *data, unsigned int data_len, 205 int timeout_ms) 206 { 207 struct sockaddr_storage addr; 208 socklen_t addrlen = sizeof(addr); 209 struct sockaddr_in *addr_in; 210 int fd, ret; 211 212 if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) { 213 log_err("Failed to get server addr"); 214 return -1; 215 } 216 217 addr_in = (struct sockaddr_in *)&addr; 218 fd = socket(addr_in->sin_family, SOCK_STREAM, 0); 219 if (fd < 0) { 220 log_err("Failed to create client socket"); 221 return -1; 222 } 223 224 if (settimeo(fd, timeout_ms)) 225 goto error_close; 226 227 ret = sendto(fd, data, data_len, MSG_FASTOPEN, (struct sockaddr *)&addr, 228 addrlen); 229 if (ret != data_len) { 230 log_err("sendto(data, %u) != %d\n", data_len, ret); 231 goto error_close; 232 } 233 234 return fd; 235 236 error_close: 237 save_errno_close(fd); 238 return -1; 239 } 240 241 static int connect_fd_to_addr(int fd, 242 const struct sockaddr_storage *addr, 243 socklen_t addrlen, const bool must_fail) 244 { 245 int ret; 246 247 errno = 0; 248 ret = connect(fd, (const struct sockaddr *)addr, addrlen); 249 if (must_fail) { 250 if (!ret) { 251 log_err("Unexpected success to connect to server"); 252 return -1; 253 } 254 if (errno != EPERM) { 255 log_err("Unexpected error from connect to server"); 256 return -1; 257 } 258 } else { 259 if (ret) { 260 log_err("Failed to connect to server"); 261 return -1; 262 } 263 } 264 265 return 0; 266 } 267 268 int connect_to_addr(int type, const struct sockaddr_storage *addr, socklen_t addrlen, 269 const struct network_helper_opts *opts) 270 { 271 int fd; 272 273 if (!opts) 274 opts = &default_opts; 275 276 fd = socket(addr->ss_family, type, opts->proto); 277 if (fd < 0) { 278 log_err("Failed to create client socket"); 279 return -1; 280 } 281 282 if (settimeo(fd, opts->timeout_ms)) 283 goto error_close; 284 285 if (connect_fd_to_addr(fd, addr, addrlen, opts->must_fail)) 286 goto error_close; 287 288 return fd; 289 290 error_close: 291 save_errno_close(fd); 292 return -1; 293 } 294 295 int connect_to_fd_opts(int server_fd, const struct network_helper_opts *opts) 296 { 297 struct sockaddr_storage addr; 298 struct sockaddr_in *addr_in; 299 socklen_t addrlen, optlen; 300 int fd, type, protocol; 301 302 if (!opts) 303 opts = &default_opts; 304 305 optlen = sizeof(type); 306 307 if (opts->type) { 308 type = opts->type; 309 } else { 310 if (getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &type, &optlen)) { 311 log_err("getsockopt(SOL_TYPE)"); 312 return -1; 313 } 314 } 315 316 if (opts->proto) { 317 protocol = opts->proto; 318 } else { 319 if (getsockopt(server_fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen)) { 320 log_err("getsockopt(SOL_PROTOCOL)"); 321 return -1; 322 } 323 } 324 325 addrlen = sizeof(addr); 326 if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) { 327 log_err("Failed to get server addr"); 328 return -1; 329 } 330 331 addr_in = (struct sockaddr_in *)&addr; 332 fd = socket(addr_in->sin_family, type, protocol); 333 if (fd < 0) { 334 log_err("Failed to create client socket"); 335 return -1; 336 } 337 338 if (settimeo(fd, opts->timeout_ms)) 339 goto error_close; 340 341 if (opts->cc && opts->cc[0] && 342 setsockopt(fd, SOL_TCP, TCP_CONGESTION, opts->cc, 343 strlen(opts->cc) + 1)) 344 goto error_close; 345 346 if (!opts->noconnect) 347 if (connect_fd_to_addr(fd, &addr, addrlen, opts->must_fail)) 348 goto error_close; 349 350 return fd; 351 352 error_close: 353 save_errno_close(fd); 354 return -1; 355 } 356 357 int connect_to_fd(int server_fd, int timeout_ms) 358 { 359 struct network_helper_opts opts = { 360 .timeout_ms = timeout_ms, 361 }; 362 363 return connect_to_fd_opts(server_fd, &opts); 364 } 365 366 int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms) 367 { 368 struct sockaddr_storage addr; 369 socklen_t len = sizeof(addr); 370 371 if (settimeo(client_fd, timeout_ms)) 372 return -1; 373 374 if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { 375 log_err("Failed to get server addr"); 376 return -1; 377 } 378 379 if (connect_fd_to_addr(client_fd, &addr, len, false)) 380 return -1; 381 382 return 0; 383 } 384 385 int make_sockaddr(int family, const char *addr_str, __u16 port, 386 struct sockaddr_storage *addr, socklen_t *len) 387 { 388 if (family == AF_INET) { 389 struct sockaddr_in *sin = (void *)addr; 390 391 memset(addr, 0, sizeof(*sin)); 392 sin->sin_family = AF_INET; 393 sin->sin_port = htons(port); 394 if (addr_str && 395 inet_pton(AF_INET, addr_str, &sin->sin_addr) != 1) { 396 log_err("inet_pton(AF_INET, %s)", addr_str); 397 return -1; 398 } 399 if (len) 400 *len = sizeof(*sin); 401 return 0; 402 } else if (family == AF_INET6) { 403 struct sockaddr_in6 *sin6 = (void *)addr; 404 405 memset(addr, 0, sizeof(*sin6)); 406 sin6->sin6_family = AF_INET6; 407 sin6->sin6_port = htons(port); 408 if (addr_str && 409 inet_pton(AF_INET6, addr_str, &sin6->sin6_addr) != 1) { 410 log_err("inet_pton(AF_INET6, %s)", addr_str); 411 return -1; 412 } 413 if (len) 414 *len = sizeof(*sin6); 415 return 0; 416 } else if (family == AF_UNIX) { 417 /* Note that we always use abstract unix sockets to avoid having 418 * to clean up leftover files. 419 */ 420 struct sockaddr_un *sun = (void *)addr; 421 422 memset(addr, 0, sizeof(*sun)); 423 sun->sun_family = family; 424 sun->sun_path[0] = 0; 425 strcpy(sun->sun_path + 1, addr_str); 426 if (len) 427 *len = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(addr_str); 428 return 0; 429 } 430 return -1; 431 } 432 433 char *ping_command(int family) 434 { 435 if (family == AF_INET6) { 436 /* On some systems 'ping' doesn't support IPv6, so use ping6 if it is present. */ 437 if (!system("which ping6 >/dev/null 2>&1")) 438 return "ping6"; 439 else 440 return "ping -6"; 441 } 442 return "ping"; 443 } 444 445 struct nstoken { 446 int orig_netns_fd; 447 }; 448 449 struct nstoken *open_netns(const char *name) 450 { 451 int nsfd; 452 char nspath[PATH_MAX]; 453 int err; 454 struct nstoken *token; 455 456 token = calloc(1, sizeof(struct nstoken)); 457 if (!token) { 458 log_err("Failed to malloc token"); 459 return NULL; 460 } 461 462 token->orig_netns_fd = open("/proc/self/ns/net", O_RDONLY); 463 if (token->orig_netns_fd == -1) { 464 log_err("Failed to open(/proc/self/ns/net)"); 465 goto fail; 466 } 467 468 snprintf(nspath, sizeof(nspath), "%s/%s", "/var/run/netns", name); 469 nsfd = open(nspath, O_RDONLY | O_CLOEXEC); 470 if (nsfd == -1) { 471 log_err("Failed to open(%s)", nspath); 472 goto fail; 473 } 474 475 err = setns(nsfd, CLONE_NEWNET); 476 close(nsfd); 477 if (err) { 478 log_err("Failed to setns(nsfd)"); 479 goto fail; 480 } 481 482 return token; 483 fail: 484 if (token->orig_netns_fd != -1) 485 close(token->orig_netns_fd); 486 free(token); 487 return NULL; 488 } 489 490 void close_netns(struct nstoken *token) 491 { 492 if (!token) 493 return; 494 495 if (setns(token->orig_netns_fd, CLONE_NEWNET)) 496 log_err("Failed to setns(orig_netns_fd)"); 497 close(token->orig_netns_fd); 498 free(token); 499 } 500 501 int get_socket_local_port(int sock_fd) 502 { 503 struct sockaddr_storage addr; 504 socklen_t addrlen = sizeof(addr); 505 int err; 506 507 err = getsockname(sock_fd, (struct sockaddr *)&addr, &addrlen); 508 if (err < 0) 509 return err; 510 511 if (addr.ss_family == AF_INET) { 512 struct sockaddr_in *sin = (struct sockaddr_in *)&addr; 513 514 return sin->sin_port; 515 } else if (addr.ss_family == AF_INET6) { 516 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&addr; 517 518 return sin->sin6_port; 519 } 520 521 return -1; 522 } 523 524 int get_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param) 525 { 526 struct ifreq ifr = {0}; 527 int sockfd, err; 528 529 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 530 if (sockfd < 0) 531 return -errno; 532 533 memcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 534 535 ring_param->cmd = ETHTOOL_GRINGPARAM; 536 ifr.ifr_data = (char *)ring_param; 537 538 if (ioctl(sockfd, SIOCETHTOOL, &ifr) < 0) { 539 err = errno; 540 close(sockfd); 541 return -err; 542 } 543 544 close(sockfd); 545 return 0; 546 } 547 548 int set_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param) 549 { 550 struct ifreq ifr = {0}; 551 int sockfd, err; 552 553 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 554 if (sockfd < 0) 555 return -errno; 556 557 memcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 558 559 ring_param->cmd = ETHTOOL_SRINGPARAM; 560 ifr.ifr_data = (char *)ring_param; 561 562 if (ioctl(sockfd, SIOCETHTOOL, &ifr) < 0) { 563 err = errno; 564 close(sockfd); 565 return -err; 566 } 567 568 close(sockfd); 569 return 0; 570 } 571 572 struct send_recv_arg { 573 int fd; 574 uint32_t bytes; 575 int stop; 576 }; 577 578 static void *send_recv_server(void *arg) 579 { 580 struct send_recv_arg *a = (struct send_recv_arg *)arg; 581 ssize_t nr_sent = 0, bytes = 0; 582 char batch[1500]; 583 int err = 0, fd; 584 585 fd = accept(a->fd, NULL, NULL); 586 while (fd == -1) { 587 if (errno == EINTR) 588 continue; 589 err = -errno; 590 goto done; 591 } 592 593 if (settimeo(fd, 0)) { 594 err = -errno; 595 goto done; 596 } 597 598 while (bytes < a->bytes && !READ_ONCE(a->stop)) { 599 nr_sent = send(fd, &batch, 600 MIN(a->bytes - bytes, sizeof(batch)), 0); 601 if (nr_sent == -1 && errno == EINTR) 602 continue; 603 if (nr_sent == -1) { 604 err = -errno; 605 break; 606 } 607 bytes += nr_sent; 608 } 609 610 if (bytes != a->bytes) { 611 log_err("send %zd expected %u", bytes, a->bytes); 612 if (!err) 613 err = bytes > a->bytes ? -E2BIG : -EINTR; 614 } 615 616 done: 617 if (fd >= 0) 618 close(fd); 619 if (err) { 620 WRITE_ONCE(a->stop, 1); 621 return ERR_PTR(err); 622 } 623 return NULL; 624 } 625 626 int send_recv_data(int lfd, int fd, uint32_t total_bytes) 627 { 628 ssize_t nr_recv = 0, bytes = 0; 629 struct send_recv_arg arg = { 630 .fd = lfd, 631 .bytes = total_bytes, 632 .stop = 0, 633 }; 634 pthread_t srv_thread; 635 void *thread_ret; 636 char batch[1500]; 637 int err = 0; 638 639 err = pthread_create(&srv_thread, NULL, send_recv_server, (void *)&arg); 640 if (err) { 641 log_err("Failed to pthread_create"); 642 return err; 643 } 644 645 /* recv total_bytes */ 646 while (bytes < total_bytes && !READ_ONCE(arg.stop)) { 647 nr_recv = recv(fd, &batch, 648 MIN(total_bytes - bytes, sizeof(batch)), 0); 649 if (nr_recv == -1 && errno == EINTR) 650 continue; 651 if (nr_recv == -1) { 652 err = -errno; 653 break; 654 } 655 bytes += nr_recv; 656 } 657 658 if (bytes != total_bytes) { 659 log_err("recv %zd expected %u", bytes, total_bytes); 660 if (!err) 661 err = bytes > total_bytes ? -E2BIG : -EINTR; 662 } 663 664 WRITE_ONCE(arg.stop, 1); 665 pthread_join(srv_thread, &thread_ret); 666 if (IS_ERR(thread_ret)) { 667 log_err("Failed in thread_ret %ld", PTR_ERR(thread_ret)); 668 err = err ? : PTR_ERR(thread_ret); 669 } 670 671 return err; 672 } 673