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