// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */

#include <linux/bpf.h>
#include <linux/if_link.h>
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/resource.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

#include "bpf/bpf.h"
#include "bpf/libbpf.h"

#include "xdping.h"

static int ifindex;
static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;

static void cleanup(int sig)
{
	bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
	if (sig)
		exit(1);
}

static int get_stats(int fd, __u16 count, __u32 raddr)
{
	struct pinginfo pinginfo = { 0 };
	char inaddrbuf[INET_ADDRSTRLEN];
	struct in_addr inaddr;
	__u16 i;

	inaddr.s_addr = raddr;

	printf("\nXDP RTT data:\n");

	if (bpf_map_lookup_elem(fd, &raddr, &pinginfo)) {
		perror("bpf_map_lookup elem: ");
		return 1;
	}

	for (i = 0; i < count; i++) {
		if (pinginfo.times[i] == 0)
			break;

		printf("64 bytes from %s: icmp_seq=%d ttl=64 time=%#.5f ms\n",
		       inet_ntop(AF_INET, &inaddr, inaddrbuf,
				 sizeof(inaddrbuf)),
		       count + i + 1,
		       (double)pinginfo.times[i]/1000000);
	}

	if (i < count) {
		fprintf(stderr, "Expected %d samples, got %d.\n", count, i);
		return 1;
	}

	bpf_map_delete_elem(fd, &raddr);

	return 0;
}

static void show_usage(const char *prog)
{
	fprintf(stderr,
		"usage: %s [OPTS] -I interface destination\n\n"
		"OPTS:\n"
		"    -c count		Stop after sending count requests\n"
		"			(default %d, max %d)\n"
		"    -I interface	interface name\n"
		"    -N			Run in driver mode\n"
		"    -s			Server mode\n"
		"    -S			Run in skb mode\n",
		prog, XDPING_DEFAULT_COUNT, XDPING_MAX_COUNT);
}

int main(int argc, char **argv)
{
	__u32 mode_flags = XDP_FLAGS_DRV_MODE | XDP_FLAGS_SKB_MODE;
	struct addrinfo *a, hints = { .ai_family = AF_INET };
	struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
	__u16 count = XDPING_DEFAULT_COUNT;
	struct pinginfo pinginfo = { 0 };
	const char *optstr = "c:I:NsS";
	struct bpf_program *main_prog;
	int prog_fd = -1, map_fd = -1;
	struct sockaddr_in rin;
	struct bpf_object *obj;
	struct bpf_map *map;
	char *ifname = NULL;
	char filename[256];
	int opt, ret = 1;
	__u32 raddr = 0;
	int server = 0;
	char cmd[256];

	while ((opt = getopt(argc, argv, optstr)) != -1) {
		switch (opt) {
		case 'c':
			count = atoi(optarg);
			if (count < 1 || count > XDPING_MAX_COUNT) {
				fprintf(stderr,
					"min count is 1, max count is %d\n",
					XDPING_MAX_COUNT);
				return 1;
			}
			break;
		case 'I':
			ifname = optarg;
			ifindex = if_nametoindex(ifname);
			if (!ifindex) {
				fprintf(stderr, "Could not get interface %s\n",
					ifname);
				return 1;
			}
			break;
		case 'N':
			xdp_flags |= XDP_FLAGS_DRV_MODE;
			break;
		case 's':
			/* use server program */
			server = 1;
			break;
		case 'S':
			xdp_flags |= XDP_FLAGS_SKB_MODE;
			break;
		default:
			show_usage(basename(argv[0]));
			return 1;
		}
	}

	if (!ifname) {
		show_usage(basename(argv[0]));
		return 1;
	}
	if (!server && optind == argc) {
		show_usage(basename(argv[0]));
		return 1;
	}

	if ((xdp_flags & mode_flags) == mode_flags) {
		fprintf(stderr, "-N or -S can be specified, not both.\n");
		show_usage(basename(argv[0]));
		return 1;
	}

	if (!server) {
		/* Only supports IPv4; see hints initiailization above. */
		if (getaddrinfo(argv[optind], NULL, &hints, &a) || !a) {
			fprintf(stderr, "Could not resolve %s\n", argv[optind]);
			return 1;
		}
		memcpy(&rin, a->ai_addr, sizeof(rin));
		raddr = rin.sin_addr.s_addr;
		freeaddrinfo(a);
	}

	if (setrlimit(RLIMIT_MEMLOCK, &r)) {
		perror("setrlimit(RLIMIT_MEMLOCK)");
		return 1;
	}

	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

	if (bpf_prog_load(filename, BPF_PROG_TYPE_XDP, &obj, &prog_fd)) {
		fprintf(stderr, "load of %s failed\n", filename);
		return 1;
	}

	main_prog = bpf_object__find_program_by_title(obj,
						      server ? "xdpserver" :
							       "xdpclient");
	if (main_prog)
		prog_fd = bpf_program__fd(main_prog);
	if (!main_prog || prog_fd < 0) {
		fprintf(stderr, "could not find xdping program");
		return 1;
	}

	map = bpf_map__next(NULL, obj);
	if (map)
		map_fd = bpf_map__fd(map);
	if (!map || map_fd < 0) {
		fprintf(stderr, "Could not find ping map");
		goto done;
	}

	signal(SIGINT, cleanup);
	signal(SIGTERM, cleanup);

	printf("Setting up XDP for %s, please wait...\n", ifname);

	printf("XDP setup disrupts network connectivity, hit Ctrl+C to quit\n");

	if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
		fprintf(stderr, "Link set xdp fd failed for %s\n", ifname);
		goto done;
	}

	if (server) {
		close(prog_fd);
		close(map_fd);
		printf("Running server on %s; press Ctrl+C to exit...\n",
		       ifname);
		do { } while (1);
	}

	/* Start xdping-ing from last regular ping reply, e.g. for a count
	 * of 10 ICMP requests, we start xdping-ing using reply with seq number
	 * 10.  The reason the last "real" ping RTT is much higher is that
	 * the ping program sees the ICMP reply associated with the last
	 * XDP-generated packet, so ping doesn't get a reply until XDP is done.
	 */
	pinginfo.seq = htons(count);
	pinginfo.count = count;

	if (bpf_map_update_elem(map_fd, &raddr, &pinginfo, BPF_ANY)) {
		fprintf(stderr, "could not communicate with BPF map: %s\n",
			strerror(errno));
		cleanup(0);
		goto done;
	}

	/* We need to wait for XDP setup to complete. */
	sleep(10);

	snprintf(cmd, sizeof(cmd), "ping -c %d -I %s %s",
		 count, ifname, argv[optind]);

	printf("\nNormal ping RTT data\n");
	printf("[Ignore final RTT; it is distorted by XDP using the reply]\n");

	ret = system(cmd);

	if (!ret)
		ret = get_stats(map_fd, count, raddr);

	cleanup(0);

done:
	if (prog_fd > 0)
		close(prog_fd);
	if (map_fd > 0)
		close(map_fd);

	return ret;
}
