// 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;
}
