// SPDX-License-Identifier: GPL-2.0
#include <uapi/linux/bpf.h>
#include <uapi/linux/netdev.h>
#include <linux/if_link.h>
#include <signal.h>
#include <argp.h>
#include <net/if.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <pthread.h>

#include <network_helpers.h>

#include "xdp_features.skel.h"
#include "xdp_features.h"

#define RED(str)	"\033[0;31m" str "\033[0m"
#define GREEN(str)	"\033[0;32m" str "\033[0m"
#define YELLOW(str)	"\033[0;33m" str "\033[0m"

static struct env {
	bool verbosity;
	int ifindex;
	bool is_tester;
	struct {
		enum netdev_xdp_act drv_feature;
		enum xdp_action action;
	} feature;
	struct sockaddr_storage dut_ctrl_addr;
	struct sockaddr_storage dut_addr;
	struct sockaddr_storage tester_addr;
} env;

#define BUFSIZE		128

void test__fail(void) { /* for network_helpers.c */ }

static int libbpf_print_fn(enum libbpf_print_level level,
			   const char *format, va_list args)
{
	if (level == LIBBPF_DEBUG && !env.verbosity)
		return 0;
	return vfprintf(stderr, format, args);
}

static volatile bool exiting;

static void sig_handler(int sig)
{
	exiting = true;
}

const char *argp_program_version = "xdp-features 0.0";
const char argp_program_doc[] =
"XDP features detection application.\n"
"\n"
"XDP features application checks the XDP advertised features match detected ones.\n"
"\n"
"USAGE: ./xdp-features [-vt] [-f <xdp-feature>] [-D <dut-data-ip>] [-T <tester-data-ip>] [-C <dut-ctrl-ip>] <iface-name>\n"
"\n"
"dut-data-ip, tester-data-ip, dut-ctrl-ip: IPv6 or IPv4-mapped-IPv6 addresses;\n"
"\n"
"XDP features\n:"
"- XDP_PASS\n"
"- XDP_DROP\n"
"- XDP_ABORTED\n"
"- XDP_REDIRECT\n"
"- XDP_NDO_XMIT\n"
"- XDP_TX\n";

static const struct argp_option opts[] = {
	{ "verbose", 'v', NULL, 0, "Verbose debug output" },
	{ "tester", 't', NULL, 0, "Tester mode" },
	{ "feature", 'f', "XDP-FEATURE", 0, "XDP feature to test" },
	{ "dut_data_ip", 'D', "DUT-DATA-IP", 0, "DUT IP data channel" },
	{ "dut_ctrl_ip", 'C', "DUT-CTRL-IP", 0, "DUT IP control channel" },
	{ "tester_data_ip", 'T', "TESTER-DATA-IP", 0, "Tester IP data channel" },
	{},
};

static int get_xdp_feature(const char *arg)
{
	if (!strcmp(arg, "XDP_PASS")) {
		env.feature.action = XDP_PASS;
		env.feature.drv_feature = NETDEV_XDP_ACT_BASIC;
	} else if (!strcmp(arg, "XDP_DROP")) {
		env.feature.drv_feature = NETDEV_XDP_ACT_BASIC;
		env.feature.action = XDP_DROP;
	} else if (!strcmp(arg, "XDP_ABORTED")) {
		env.feature.drv_feature = NETDEV_XDP_ACT_BASIC;
		env.feature.action = XDP_ABORTED;
	} else if (!strcmp(arg, "XDP_TX")) {
		env.feature.drv_feature = NETDEV_XDP_ACT_BASIC;
		env.feature.action = XDP_TX;
	} else if (!strcmp(arg, "XDP_REDIRECT")) {
		env.feature.drv_feature = NETDEV_XDP_ACT_REDIRECT;
		env.feature.action = XDP_REDIRECT;
	} else if (!strcmp(arg, "XDP_NDO_XMIT")) {
		env.feature.drv_feature = NETDEV_XDP_ACT_NDO_XMIT;
	} else {
		return -EINVAL;
	}

	return 0;
}

static char *get_xdp_feature_str(void)
{
	switch (env.feature.action) {
	case XDP_PASS:
		return YELLOW("XDP_PASS");
	case XDP_DROP:
		return YELLOW("XDP_DROP");
	case XDP_ABORTED:
		return YELLOW("XDP_ABORTED");
	case XDP_TX:
		return YELLOW("XDP_TX");
	case XDP_REDIRECT:
		return YELLOW("XDP_REDIRECT");
	default:
		break;
	}

	if (env.feature.drv_feature == NETDEV_XDP_ACT_NDO_XMIT)
		return YELLOW("XDP_NDO_XMIT");

	return "";
}

static error_t parse_arg(int key, char *arg, struct argp_state *state)
{
	switch (key) {
	case 'v':
		env.verbosity = true;
		break;
	case 't':
		env.is_tester = true;
		break;
	case 'f':
		if (get_xdp_feature(arg) < 0) {
			fprintf(stderr, "Invalid xdp feature: %s\n", arg);
			argp_usage(state);
			return ARGP_ERR_UNKNOWN;
		}
		break;
	case 'D':
		if (make_sockaddr(AF_INET6, arg, DUT_ECHO_PORT,
				  &env.dut_addr, NULL)) {
			fprintf(stderr, "Invalid DUT address: %s\n", arg);
			return ARGP_ERR_UNKNOWN;
		}
		break;
	case 'C':
		if (make_sockaddr(AF_INET6, arg, DUT_CTRL_PORT,
				  &env.dut_ctrl_addr, NULL)) {
			fprintf(stderr, "Invalid DUT CTRL address: %s\n", arg);
			return ARGP_ERR_UNKNOWN;
		}
		break;
	case 'T':
		if (make_sockaddr(AF_INET6, arg, 0, &env.tester_addr, NULL)) {
			fprintf(stderr, "Invalid Tester address: %s\n", arg);
			return ARGP_ERR_UNKNOWN;
		}
		break;
	case ARGP_KEY_ARG:
		errno = 0;
		if (strlen(arg) >= IF_NAMESIZE) {
			fprintf(stderr, "Invalid device name: %s\n", arg);
			argp_usage(state);
			return ARGP_ERR_UNKNOWN;
		}

		env.ifindex = if_nametoindex(arg);
		if (!env.ifindex)
			env.ifindex = strtoul(arg, NULL, 0);
		if (!env.ifindex) {
			fprintf(stderr,
				"Bad interface index or name (%d): %s\n",
				errno, strerror(errno));
			argp_usage(state);
			return ARGP_ERR_UNKNOWN;
		}
		break;
	default:
		return ARGP_ERR_UNKNOWN;
	}

	return 0;
}

static const struct argp argp = {
	.options = opts,
	.parser = parse_arg,
	.doc = argp_program_doc,
};

static void set_env_default(void)
{
	env.feature.drv_feature = NETDEV_XDP_ACT_NDO_XMIT;
	env.feature.action = -EINVAL;
	env.ifindex = -ENODEV;
	make_sockaddr(AF_INET6, "::ffff:127.0.0.1", DUT_CTRL_PORT,
		      &env.dut_ctrl_addr, NULL);
	make_sockaddr(AF_INET6, "::ffff:127.0.0.1", DUT_ECHO_PORT,
		      &env.dut_addr, NULL);
	make_sockaddr(AF_INET6, "::ffff:127.0.0.1", 0, &env.tester_addr, NULL);
}

static void *dut_echo_thread(void *arg)
{
	unsigned char buf[sizeof(struct tlv_hdr)];
	int sockfd = *(int *)arg;

	while (!exiting) {
		struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
		struct sockaddr_storage addr;
		socklen_t addrlen;
		size_t n;

		n = recvfrom(sockfd, buf, sizeof(buf), MSG_WAITALL,
			     (struct sockaddr *)&addr, &addrlen);
		if (n != ntohs(tlv->len))
			continue;

		if (ntohs(tlv->type) != CMD_ECHO)
			continue;

		sendto(sockfd, buf, sizeof(buf), MSG_NOSIGNAL | MSG_CONFIRM,
		       (struct sockaddr *)&addr, addrlen);
	}

	pthread_exit((void *)0);
	close(sockfd);

	return NULL;
}

static int dut_run_echo_thread(pthread_t *t, int *sockfd)
{
	int err;

	sockfd = start_reuseport_server(AF_INET6, SOCK_DGRAM, NULL,
					DUT_ECHO_PORT, 0, 1);
	if (!sockfd) {
		fprintf(stderr, "Failed to create echo socket\n");
		return -errno;
	}

	/* start echo channel */
	err = pthread_create(t, NULL, dut_echo_thread, sockfd);
	if (err) {
		fprintf(stderr, "Failed creating dut_echo thread: %s\n",
			strerror(-err));
		free_fds(sockfd, 1);
		return -EINVAL;
	}

	return 0;
}

static int dut_attach_xdp_prog(struct xdp_features *skel, int flags)
{
	enum xdp_action action = env.feature.action;
	struct bpf_program *prog;
	unsigned int key = 0;
	int err, fd = 0;

	if (env.feature.drv_feature == NETDEV_XDP_ACT_NDO_XMIT) {
		struct bpf_devmap_val entry = {
			.ifindex = env.ifindex,
		};

		err = bpf_map__update_elem(skel->maps.dev_map,
					   &key, sizeof(key),
					   &entry, sizeof(entry), 0);
		if (err < 0)
			return err;

		fd = bpf_program__fd(skel->progs.xdp_do_redirect_cpumap);
		action = XDP_REDIRECT;
	}

	switch (action) {
	case XDP_TX:
		prog = skel->progs.xdp_do_tx;
		break;
	case XDP_DROP:
		prog = skel->progs.xdp_do_drop;
		break;
	case XDP_ABORTED:
		prog = skel->progs.xdp_do_aborted;
		break;
	case XDP_PASS:
		prog = skel->progs.xdp_do_pass;
		break;
	case XDP_REDIRECT: {
		struct bpf_cpumap_val entry = {
			.qsize = 2048,
			.bpf_prog.fd = fd,
		};

		err = bpf_map__update_elem(skel->maps.cpu_map,
					   &key, sizeof(key),
					   &entry, sizeof(entry), 0);
		if (err < 0)
			return err;

		prog = skel->progs.xdp_do_redirect;
		break;
	}
	default:
		return -EINVAL;
	}

	err = bpf_xdp_attach(env.ifindex, bpf_program__fd(prog), flags, NULL);
	if (err)
		fprintf(stderr,
			"Failed to attach XDP program to ifindex %d\n",
			env.ifindex);
	return err;
}

static int recv_msg(int sockfd, void *buf, size_t bufsize, void *val,
		    size_t val_size)
{
	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
	size_t len;

	len = recv(sockfd, buf, bufsize, 0);
	if (len != ntohs(tlv->len) || len < sizeof(*tlv))
		return -EINVAL;

	if (val) {
		len -= sizeof(*tlv);
		if (len > val_size)
			return -ENOMEM;

		memcpy(val, tlv->data, len);
	}

	return 0;
}

static int dut_run(struct xdp_features *skel)
{
	int flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE;
	int state, err, *sockfd, ctrl_sockfd, echo_sockfd;
	struct sockaddr_storage ctrl_addr;
	pthread_t dut_thread;
	socklen_t addrlen;

	sockfd = start_reuseport_server(AF_INET6, SOCK_STREAM, NULL,
					DUT_CTRL_PORT, 0, 1);
	if (!sockfd) {
		fprintf(stderr, "Failed to create DUT socket\n");
		return -errno;
	}

	ctrl_sockfd = accept(*sockfd, (struct sockaddr *)&ctrl_addr, &addrlen);
	if (ctrl_sockfd < 0) {
		fprintf(stderr, "Failed to accept connection on DUT socket\n");
		free_fds(sockfd, 1);
		return -errno;
	}

	/* CTRL loop */
	while (!exiting) {
		unsigned char buf[BUFSIZE] = {};
		struct tlv_hdr *tlv = (struct tlv_hdr *)buf;

		err = recv_msg(ctrl_sockfd, buf, BUFSIZE, NULL, 0);
		if (err)
			continue;

		switch (ntohs(tlv->type)) {
		case CMD_START: {
			if (state == CMD_START)
				continue;

			state = CMD_START;
			/* Load the XDP program on the DUT */
			err = dut_attach_xdp_prog(skel, flags);
			if (err)
				goto out;

			err = dut_run_echo_thread(&dut_thread, &echo_sockfd);
			if (err < 0)
				goto out;

			tlv->type = htons(CMD_ACK);
			tlv->len = htons(sizeof(*tlv));
			err = send(ctrl_sockfd, buf, sizeof(*tlv), 0);
			if (err < 0)
				goto end_thread;
			break;
		}
		case CMD_STOP:
			if (state != CMD_START)
				break;

			state = CMD_STOP;

			exiting = true;
			bpf_xdp_detach(env.ifindex, flags, NULL);

			tlv->type = htons(CMD_ACK);
			tlv->len = htons(sizeof(*tlv));
			err = send(ctrl_sockfd, buf, sizeof(*tlv), 0);
			goto end_thread;
		case CMD_GET_XDP_CAP: {
			LIBBPF_OPTS(bpf_xdp_query_opts, opts);
			unsigned long long val;
			size_t n;

			err = bpf_xdp_query(env.ifindex, XDP_FLAGS_DRV_MODE,
					    &opts);
			if (err) {
				fprintf(stderr,
					"Failed to query XDP cap for ifindex %d\n",
					env.ifindex);
				goto end_thread;
			}

			tlv->type = htons(CMD_ACK);
			n = sizeof(*tlv) + sizeof(opts.feature_flags);
			tlv->len = htons(n);

			val = htobe64(opts.feature_flags);
			memcpy(tlv->data, &val, sizeof(val));

			err = send(ctrl_sockfd, buf, n, 0);
			if (err < 0)
				goto end_thread;
			break;
		}
		case CMD_GET_STATS: {
			unsigned int key = 0, val;
			size_t n;

			err = bpf_map__lookup_elem(skel->maps.dut_stats,
						   &key, sizeof(key),
						   &val, sizeof(val), 0);
			if (err) {
				fprintf(stderr, "bpf_map_lookup_elem failed\n");
				goto end_thread;
			}

			tlv->type = htons(CMD_ACK);
			n = sizeof(*tlv) + sizeof(val);
			tlv->len = htons(n);

			val = htonl(val);
			memcpy(tlv->data, &val, sizeof(val));

			err = send(ctrl_sockfd, buf, n, 0);
			if (err < 0)
				goto end_thread;
			break;
		}
		default:
			break;
		}
	}

end_thread:
	pthread_join(dut_thread, NULL);
out:
	bpf_xdp_detach(env.ifindex, flags, NULL);
	close(ctrl_sockfd);
	free_fds(sockfd, 1);

	return err;
}

static bool tester_collect_detected_cap(struct xdp_features *skel,
					unsigned int dut_stats)
{
	unsigned int err, key = 0, val;

	if (!dut_stats)
		return false;

	err = bpf_map__lookup_elem(skel->maps.stats, &key, sizeof(key),
				   &val, sizeof(val), 0);
	if (err) {
		fprintf(stderr, "bpf_map_lookup_elem failed\n");
		return false;
	}

	switch (env.feature.action) {
	case XDP_PASS:
	case XDP_TX:
	case XDP_REDIRECT:
		return val > 0;
	case XDP_DROP:
	case XDP_ABORTED:
		return val == 0;
	default:
		break;
	}

	if (env.feature.drv_feature == NETDEV_XDP_ACT_NDO_XMIT)
		return val > 0;

	return false;
}

static int send_and_recv_msg(int sockfd, enum test_commands cmd, void *val,
			     size_t val_size)
{
	unsigned char buf[BUFSIZE] = {};
	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
	int err;

	tlv->type = htons(cmd);
	tlv->len = htons(sizeof(*tlv));

	err = send(sockfd, buf, sizeof(*tlv), 0);
	if (err < 0)
		return err;

	err = recv_msg(sockfd, buf, BUFSIZE, val, val_size);
	if (err < 0)
		return err;

	return ntohs(tlv->type) == CMD_ACK ? 0 : -EINVAL;
}

static int send_echo_msg(void)
{
	unsigned char buf[sizeof(struct tlv_hdr)];
	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
	int sockfd, n;

	sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
	if (sockfd < 0) {
		fprintf(stderr, "Failed to create echo socket\n");
		return -errno;
	}

	tlv->type = htons(CMD_ECHO);
	tlv->len = htons(sizeof(*tlv));

	n = sendto(sockfd, buf, sizeof(*tlv), MSG_NOSIGNAL | MSG_CONFIRM,
		   (struct sockaddr *)&env.dut_addr, sizeof(env.dut_addr));
	close(sockfd);

	return n == ntohs(tlv->len) ? 0 : -EINVAL;
}

static int tester_run(struct xdp_features *skel)
{
	int flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE;
	unsigned long long advertised_feature;
	struct bpf_program *prog;
	unsigned int stats;
	int i, err, sockfd;
	bool detected_cap;

	sockfd = socket(AF_INET6, SOCK_STREAM, 0);
	if (sockfd < 0) {
		fprintf(stderr, "Failed to create tester socket\n");
		return -errno;
	}

	if (settimeo(sockfd, 1000) < 0)
		return -EINVAL;

	err = connect(sockfd, (struct sockaddr *)&env.dut_ctrl_addr,
		      sizeof(env.dut_ctrl_addr));
	if (err) {
		fprintf(stderr, "Failed to connect to the DUT\n");
		return -errno;
	}

	err = send_and_recv_msg(sockfd, CMD_GET_XDP_CAP, &advertised_feature,
				sizeof(advertised_feature));
	if (err < 0) {
		close(sockfd);
		return err;
	}

	advertised_feature = be64toh(advertised_feature);

	if (env.feature.drv_feature == NETDEV_XDP_ACT_NDO_XMIT ||
	    env.feature.action == XDP_TX)
		prog = skel->progs.xdp_tester_check_tx;
	else
		prog = skel->progs.xdp_tester_check_rx;

	err = bpf_xdp_attach(env.ifindex, bpf_program__fd(prog), flags, NULL);
	if (err) {
		fprintf(stderr, "Failed to attach XDP program to ifindex %d\n",
			env.ifindex);
		goto out;
	}

	err = send_and_recv_msg(sockfd, CMD_START, NULL, 0);
	if (err)
		goto out;

	for (i = 0; i < 10 && !exiting; i++) {
		err = send_echo_msg();
		if (err < 0)
			goto out;

		sleep(1);
	}

	err = send_and_recv_msg(sockfd, CMD_GET_STATS, &stats, sizeof(stats));
	if (err)
		goto out;

	/* stop the test */
	err = send_and_recv_msg(sockfd, CMD_STOP, NULL, 0);
	/* send a new echo message to wake echo thread of the dut */
	send_echo_msg();

	detected_cap = tester_collect_detected_cap(skel, ntohl(stats));

	fprintf(stdout, "Feature %s: [%s][%s]\n", get_xdp_feature_str(),
		detected_cap ? GREEN("DETECTED") : RED("NOT DETECTED"),
		env.feature.drv_feature & advertised_feature ? GREEN("ADVERTISED")
							     : RED("NOT ADVERTISED"));
out:
	bpf_xdp_detach(env.ifindex, flags, NULL);
	close(sockfd);
	return err < 0 ? err : 0;
}

int main(int argc, char **argv)
{
	struct xdp_features *skel;
	int err;

	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
	libbpf_set_print(libbpf_print_fn);

	signal(SIGINT, sig_handler);
	signal(SIGTERM, sig_handler);

	set_env_default();

	/* Parse command line arguments */
	err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
	if (err)
		return err;

	if (env.ifindex < 0) {
		fprintf(stderr, "Invalid ifindex\n");
		return -ENODEV;
	}

	/* Load and verify BPF application */
	skel = xdp_features__open();
	if (!skel) {
		fprintf(stderr, "Failed to open and load BPF skeleton\n");
		return -EINVAL;
	}

	skel->rodata->tester_addr =
		((struct sockaddr_in6 *)&env.tester_addr)->sin6_addr;
	skel->rodata->dut_addr =
		((struct sockaddr_in6 *)&env.dut_addr)->sin6_addr;

	/* Load & verify BPF programs */
	err = xdp_features__load(skel);
	if (err) {
		fprintf(stderr, "Failed to load and verify BPF skeleton\n");
		goto cleanup;
	}

	err = xdp_features__attach(skel);
	if (err) {
		fprintf(stderr, "Failed to attach BPF skeleton\n");
		goto cleanup;
	}

	if (env.is_tester) {
		/* Tester */
		fprintf(stdout, "Starting tester on device %d\n", env.ifindex);
		err = tester_run(skel);
	} else {
		/* DUT */
		fprintf(stdout, "Starting DUT on device %d\n", env.ifindex);
		err = dut_run(skel);
	}

cleanup:
	xdp_features__destroy(skel);

	return err < 0 ? -err : 0;
}
