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 int connect_to_addr(int type, const struct sockaddr_storage *addr, socklen_t addrlen, 281 const struct network_helper_opts *opts) 282 { 283 int fd; 284 285 if (!opts) 286 opts = &default_opts; 287 288 fd = client_socket(addr->ss_family, type, opts); 289 if (fd < 0) { 290 log_err("Failed to create client socket"); 291 return -1; 292 } 293 294 if (connect(fd, (const struct sockaddr *)addr, addrlen)) { 295 log_err("Failed to connect to server"); 296 save_errno_close(fd); 297 return -1; 298 } 299 300 return fd; 301 } 302 303 int connect_to_addr_str(int family, int type, const char *addr_str, __u16 port, 304 const struct network_helper_opts *opts) 305 { 306 struct sockaddr_storage addr; 307 socklen_t addrlen; 308 309 if (!opts) 310 opts = &default_opts; 311 312 if (make_sockaddr(family, addr_str, port, &addr, &addrlen)) 313 return -1; 314 315 return connect_to_addr(type, &addr, addrlen, opts); 316 } 317 318 int connect_to_fd_opts(int server_fd, const struct network_helper_opts *opts) 319 { 320 struct sockaddr_storage addr; 321 socklen_t addrlen, optlen; 322 int type; 323 324 if (!opts) 325 opts = &default_opts; 326 327 optlen = sizeof(type); 328 if (getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &type, &optlen)) { 329 log_err("getsockopt(SOL_TYPE)"); 330 return -1; 331 } 332 333 addrlen = sizeof(addr); 334 if (getsockname(server_fd, (struct sockaddr *)&addr, &addrlen)) { 335 log_err("Failed to get server addr"); 336 return -1; 337 } 338 339 return connect_to_addr(type, &addr, addrlen, opts); 340 } 341 342 int connect_to_fd(int server_fd, int timeout_ms) 343 { 344 struct network_helper_opts opts = { 345 .timeout_ms = timeout_ms, 346 }; 347 socklen_t optlen; 348 int protocol; 349 350 optlen = sizeof(protocol); 351 if (getsockopt(server_fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen)) { 352 log_err("getsockopt(SOL_PROTOCOL)"); 353 return -1; 354 } 355 opts.proto = protocol; 356 357 return connect_to_fd_opts(server_fd, &opts); 358 } 359 360 int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms) 361 { 362 struct sockaddr_storage addr; 363 socklen_t len = sizeof(addr); 364 365 if (settimeo(client_fd, timeout_ms)) 366 return -1; 367 368 if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { 369 log_err("Failed to get server addr"); 370 return -1; 371 } 372 373 if (connect(client_fd, (const struct sockaddr *)&addr, len)) { 374 log_err("Failed to connect to server"); 375 return -1; 376 } 377 378 return 0; 379 } 380 381 int make_sockaddr(int family, const char *addr_str, __u16 port, 382 struct sockaddr_storage *addr, socklen_t *len) 383 { 384 if (family == AF_INET) { 385 struct sockaddr_in *sin = (void *)addr; 386 387 memset(addr, 0, sizeof(*sin)); 388 sin->sin_family = AF_INET; 389 sin->sin_port = htons(port); 390 if (addr_str && 391 inet_pton(AF_INET, addr_str, &sin->sin_addr) != 1) { 392 log_err("inet_pton(AF_INET, %s)", addr_str); 393 return -1; 394 } 395 if (len) 396 *len = sizeof(*sin); 397 return 0; 398 } else if (family == AF_INET6) { 399 struct sockaddr_in6 *sin6 = (void *)addr; 400 401 memset(addr, 0, sizeof(*sin6)); 402 sin6->sin6_family = AF_INET6; 403 sin6->sin6_port = htons(port); 404 if (addr_str && 405 inet_pton(AF_INET6, addr_str, &sin6->sin6_addr) != 1) { 406 log_err("inet_pton(AF_INET6, %s)", addr_str); 407 return -1; 408 } 409 if (len) 410 *len = sizeof(*sin6); 411 return 0; 412 } else if (family == AF_UNIX) { 413 /* Note that we always use abstract unix sockets to avoid having 414 * to clean up leftover files. 415 */ 416 struct sockaddr_un *sun = (void *)addr; 417 418 memset(addr, 0, sizeof(*sun)); 419 sun->sun_family = family; 420 sun->sun_path[0] = 0; 421 strcpy(sun->sun_path + 1, addr_str); 422 if (len) 423 *len = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(addr_str); 424 return 0; 425 } 426 return -1; 427 } 428 429 char *ping_command(int family) 430 { 431 if (family == AF_INET6) { 432 /* On some systems 'ping' doesn't support IPv6, so use ping6 if it is present. */ 433 if (!system("which ping6 >/dev/null 2>&1")) 434 return "ping6"; 435 else 436 return "ping -6"; 437 } 438 return "ping"; 439 } 440 441 struct nstoken { 442 int orig_netns_fd; 443 }; 444 445 struct nstoken *open_netns(const char *name) 446 { 447 int nsfd; 448 char nspath[PATH_MAX]; 449 int err; 450 struct nstoken *token; 451 452 token = calloc(1, sizeof(struct nstoken)); 453 if (!token) { 454 log_err("Failed to malloc token"); 455 return NULL; 456 } 457 458 token->orig_netns_fd = open("/proc/self/ns/net", O_RDONLY); 459 if (token->orig_netns_fd == -1) { 460 log_err("Failed to open(/proc/self/ns/net)"); 461 goto fail; 462 } 463 464 snprintf(nspath, sizeof(nspath), "%s/%s", "/var/run/netns", name); 465 nsfd = open(nspath, O_RDONLY | O_CLOEXEC); 466 if (nsfd == -1) { 467 log_err("Failed to open(%s)", nspath); 468 goto fail; 469 } 470 471 err = setns(nsfd, CLONE_NEWNET); 472 close(nsfd); 473 if (err) { 474 log_err("Failed to setns(nsfd)"); 475 goto fail; 476 } 477 478 return token; 479 fail: 480 if (token->orig_netns_fd != -1) 481 close(token->orig_netns_fd); 482 free(token); 483 return NULL; 484 } 485 486 void close_netns(struct nstoken *token) 487 { 488 if (!token) 489 return; 490 491 if (setns(token->orig_netns_fd, CLONE_NEWNET)) 492 log_err("Failed to setns(orig_netns_fd)"); 493 close(token->orig_netns_fd); 494 free(token); 495 } 496 497 int get_socket_local_port(int sock_fd) 498 { 499 struct sockaddr_storage addr; 500 socklen_t addrlen = sizeof(addr); 501 int err; 502 503 err = getsockname(sock_fd, (struct sockaddr *)&addr, &addrlen); 504 if (err < 0) 505 return err; 506 507 if (addr.ss_family == AF_INET) { 508 struct sockaddr_in *sin = (struct sockaddr_in *)&addr; 509 510 return sin->sin_port; 511 } else if (addr.ss_family == AF_INET6) { 512 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&addr; 513 514 return sin->sin6_port; 515 } 516 517 return -1; 518 } 519 520 int get_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param) 521 { 522 struct ifreq ifr = {0}; 523 int sockfd, err; 524 525 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 526 if (sockfd < 0) 527 return -errno; 528 529 memcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 530 531 ring_param->cmd = ETHTOOL_GRINGPARAM; 532 ifr.ifr_data = (char *)ring_param; 533 534 if (ioctl(sockfd, SIOCETHTOOL, &ifr) < 0) { 535 err = errno; 536 close(sockfd); 537 return -err; 538 } 539 540 close(sockfd); 541 return 0; 542 } 543 544 int set_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param) 545 { 546 struct ifreq ifr = {0}; 547 int sockfd, err; 548 549 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 550 if (sockfd < 0) 551 return -errno; 552 553 memcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 554 555 ring_param->cmd = ETHTOOL_SRINGPARAM; 556 ifr.ifr_data = (char *)ring_param; 557 558 if (ioctl(sockfd, SIOCETHTOOL, &ifr) < 0) { 559 err = errno; 560 close(sockfd); 561 return -err; 562 } 563 564 close(sockfd); 565 return 0; 566 } 567 568 struct send_recv_arg { 569 int fd; 570 uint32_t bytes; 571 int stop; 572 }; 573 574 static void *send_recv_server(void *arg) 575 { 576 struct send_recv_arg *a = (struct send_recv_arg *)arg; 577 ssize_t nr_sent = 0, bytes = 0; 578 char batch[1500]; 579 int err = 0, fd; 580 581 fd = accept(a->fd, NULL, NULL); 582 while (fd == -1) { 583 if (errno == EINTR) 584 continue; 585 err = -errno; 586 goto done; 587 } 588 589 if (settimeo(fd, 0)) { 590 err = -errno; 591 goto done; 592 } 593 594 while (bytes < a->bytes && !READ_ONCE(a->stop)) { 595 nr_sent = send(fd, &batch, 596 MIN(a->bytes - bytes, sizeof(batch)), 0); 597 if (nr_sent == -1 && errno == EINTR) 598 continue; 599 if (nr_sent == -1) { 600 err = -errno; 601 break; 602 } 603 bytes += nr_sent; 604 } 605 606 if (bytes != a->bytes) { 607 log_err("send %zd expected %u", bytes, a->bytes); 608 if (!err) 609 err = bytes > a->bytes ? -E2BIG : -EINTR; 610 } 611 612 done: 613 if (fd >= 0) 614 close(fd); 615 if (err) { 616 WRITE_ONCE(a->stop, 1); 617 return ERR_PTR(err); 618 } 619 return NULL; 620 } 621 622 int send_recv_data(int lfd, int fd, uint32_t total_bytes) 623 { 624 ssize_t nr_recv = 0, bytes = 0; 625 struct send_recv_arg arg = { 626 .fd = lfd, 627 .bytes = total_bytes, 628 .stop = 0, 629 }; 630 pthread_t srv_thread; 631 void *thread_ret; 632 char batch[1500]; 633 int err = 0; 634 635 err = pthread_create(&srv_thread, NULL, send_recv_server, (void *)&arg); 636 if (err) { 637 log_err("Failed to pthread_create"); 638 return err; 639 } 640 641 /* recv total_bytes */ 642 while (bytes < total_bytes && !READ_ONCE(arg.stop)) { 643 nr_recv = recv(fd, &batch, 644 MIN(total_bytes - bytes, sizeof(batch)), 0); 645 if (nr_recv == -1 && errno == EINTR) 646 continue; 647 if (nr_recv == -1) { 648 err = -errno; 649 break; 650 } 651 bytes += nr_recv; 652 } 653 654 if (bytes != total_bytes) { 655 log_err("recv %zd expected %u", bytes, total_bytes); 656 if (!err) 657 err = bytes > total_bytes ? -E2BIG : -EINTR; 658 } 659 660 WRITE_ONCE(arg.stop, 1); 661 pthread_join(srv_thread, &thread_ret); 662 if (IS_ERR(thread_ret)) { 663 log_err("Failed in thread_ret %ld", PTR_ERR(thread_ret)); 664 err = err ? : PTR_ERR(thread_ret); 665 } 666 667 return err; 668 } 669