^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/if_link.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <arpa/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <assert.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <libgen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sys/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sys/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <netdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "bpf/bpf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "bpf/libbpf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "xdping.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static int ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static void cleanup(int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int get_stats(int fd, __u16 count, __u32 raddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct pinginfo pinginfo = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) char inaddrbuf[INET_ADDRSTRLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct in_addr inaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) __u16 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) inaddr.s_addr = raddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) printf("\nXDP RTT data:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (bpf_map_lookup_elem(fd, &raddr, &pinginfo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) perror("bpf_map_lookup elem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (pinginfo.times[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) printf("64 bytes from %s: icmp_seq=%d ttl=64 time=%#.5f ms\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) inet_ntop(AF_INET, &inaddr, inaddrbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) sizeof(inaddrbuf)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) count + i + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) (double)pinginfo.times[i]/1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (i < count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) fprintf(stderr, "Expected %d samples, got %d.\n", count, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) bpf_map_delete_elem(fd, &raddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static void show_usage(const char *prog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) "usage: %s [OPTS] -I interface destination\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "OPTS:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) " -c count Stop after sending count requests\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) " (default %d, max %d)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) " -I interface interface name\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) " -N Run in driver mode\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) " -s Server mode\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) " -S Run in skb mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) prog, XDPING_DEFAULT_COUNT, XDPING_MAX_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) __u32 mode_flags = XDP_FLAGS_DRV_MODE | XDP_FLAGS_SKB_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct addrinfo *a, hints = { .ai_family = AF_INET };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) __u16 count = XDPING_DEFAULT_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct pinginfo pinginfo = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) const char *optstr = "c:I:NsS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct bpf_program *main_prog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int prog_fd = -1, map_fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct sockaddr_in rin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct bpf_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct bpf_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) char *ifname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) char filename[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int opt, ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __u32 raddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int server = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) char cmd[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) while ((opt = getopt(argc, argv, optstr)) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) count = atoi(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (count < 1 || count > XDPING_MAX_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) "min count is 1, max count is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) XDPING_MAX_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ifname = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ifindex = if_nametoindex(ifname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!ifindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) fprintf(stderr, "Could not get interface %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ifname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) xdp_flags |= XDP_FLAGS_DRV_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* use server program */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) server = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) xdp_flags |= XDP_FLAGS_SKB_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) show_usage(basename(argv[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (!ifname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) show_usage(basename(argv[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!server && optind == argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) show_usage(basename(argv[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if ((xdp_flags & mode_flags) == mode_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) fprintf(stderr, "-N or -S can be specified, not both.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) show_usage(basename(argv[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Only supports IPv4; see hints initiailization above. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (getaddrinfo(argv[optind], NULL, &hints, &a) || !a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) fprintf(stderr, "Could not resolve %s\n", argv[optind]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) memcpy(&rin, a->ai_addr, sizeof(rin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) raddr = rin.sin_addr.s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) freeaddrinfo(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (setrlimit(RLIMIT_MEMLOCK, &r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) perror("setrlimit(RLIMIT_MEMLOCK)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (bpf_prog_load(filename, BPF_PROG_TYPE_XDP, &obj, &prog_fd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) fprintf(stderr, "load of %s failed\n", filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) main_prog = bpf_object__find_program_by_title(obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) server ? "xdpserver" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) "xdpclient");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (main_prog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) prog_fd = bpf_program__fd(main_prog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!main_prog || prog_fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) fprintf(stderr, "could not find xdping program");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) map = bpf_map__next(NULL, obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) map_fd = bpf_map__fd(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!map || map_fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) fprintf(stderr, "Could not find ping map");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) signal(SIGINT, cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) signal(SIGTERM, cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) printf("Setting up XDP for %s, please wait...\n", ifname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) printf("XDP setup disrupts network connectivity, hit Ctrl+C to quit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) fprintf(stderr, "Link set xdp fd failed for %s\n", ifname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) close(prog_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) close(map_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) printf("Running server on %s; press Ctrl+C to exit...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ifname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) do { } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Start xdping-ing from last regular ping reply, e.g. for a count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * of 10 ICMP requests, we start xdping-ing using reply with seq number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * 10. The reason the last "real" ping RTT is much higher is that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * the ping program sees the ICMP reply associated with the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * XDP-generated packet, so ping doesn't get a reply until XDP is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pinginfo.seq = htons(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) pinginfo.count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (bpf_map_update_elem(map_fd, &raddr, &pinginfo, BPF_ANY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) fprintf(stderr, "could not communicate with BPF map: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) cleanup(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* We need to wait for XDP setup to complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) snprintf(cmd, sizeof(cmd), "ping -c %d -I %s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) count, ifname, argv[optind]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) printf("\nNormal ping RTT data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) printf("[Ignore final RTT; it is distorted by XDP using the reply]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = system(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ret = get_stats(map_fd, count, raddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) cleanup(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (prog_fd > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) close(prog_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (map_fd > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) close(map_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }