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