// 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 "bpf_util.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;
	char ifname[IF_NAMESIZE];
	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 address assigned to the Device Under Test: %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 address assigned to the Device Under Test: %s\n",
				arg);
			return ARGP_ERR_UNKNOWN;
		}
		break;
	case 'T':
		if (make_sockaddr(AF_INET6, arg, 0, &env.tester_addr, NULL)) {
			fprintf(stderr,
				"Invalid address assigned to the Tester device: %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 || !if_indextoname(env.ifindex, env.ifname)) {
			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;
	strscpy(env.ifname, "unknown");
	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 creating data UDP socket on device %s\n",
			env.ifname);
		return -errno;
	}

	/* start echo channel */
	err = pthread_create(t, NULL, dut_echo_thread, sockfd);
	if (err) {
		fprintf(stderr,
			"Failed creating data UDP thread on device %s: %s\n",
			env.ifname, 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 attaching XDP program to device %s\n",
			env.ifname);
	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 = 0, *sockfd, ctrl_sockfd, echo_sockfd;
	struct sockaddr_storage ctrl_addr;
	pthread_t dut_thread = 0;
	socklen_t addrlen;

	sockfd = start_reuseport_server(AF_INET6, SOCK_STREAM, NULL,
					DUT_CTRL_PORT, 0, 1);
	if (!sockfd) {
		fprintf(stderr,
			"Failed creating control socket on device %s\n", env.ifname);
		return -errno;
	}

	ctrl_sockfd = accept(*sockfd, (struct sockaddr *)&ctrl_addr, &addrlen);
	if (ctrl_sockfd < 0) {
		fprintf(stderr,
			"Failed accepting connections on device %s control socket\n",
			env.ifname);
		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 querying XDP cap for device %s\n",
					env.ifname);
				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 (%d)\n", err);
				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 (%d)\n", err);
		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 creating data UDP socket on device %s\n",
			env.ifname);
		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 creating tester service control 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 connecting to the Device Under Test control socket\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 attaching XDP program to device %s\n",
			env.ifname);
		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 device name %s\n", env.ifname);
		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 service on device %s\n",
			env.ifname);
		err = tester_run(skel);
	} else {
		/* DUT */
		fprintf(stdout, "Starting test on device %s\n", env.ifname);
		err = dut_run(skel);
	}

cleanup:
	xdp_features__destroy(skel);

	return err < 0 ? -err : 0;
}
