// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */

#include <stdnoreturn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <sys/types.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <net/if.h>
#include <linux/if_link.h>
#include <linux/limits.h>

static unsigned int ifindex;
static __u32 attached_prog_id;
static bool attached_tc;

static void noreturn cleanup(int sig)
{
	LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
	int prog_fd;
	int err;

	if (attached_prog_id == 0)
		exit(0);

	if (attached_tc) {
		LIBBPF_OPTS(bpf_tc_hook, hook,
			    .ifindex = ifindex,
			    .attach_point = BPF_TC_INGRESS);

		err = bpf_tc_hook_destroy(&hook);
		if (err < 0) {
			fprintf(stderr, "Error: bpf_tc_hook_destroy: %s\n", strerror(-err));
			fprintf(stderr, "Failed to destroy the TC hook\n");
			exit(1);
		}
		exit(0);
	}

	prog_fd = bpf_prog_get_fd_by_id(attached_prog_id);
	if (prog_fd < 0) {
		fprintf(stderr, "Error: bpf_prog_get_fd_by_id: %s\n", strerror(-prog_fd));
		err = bpf_xdp_attach(ifindex, -1, 0, NULL);
		if (err < 0) {
			fprintf(stderr, "Error: bpf_set_link_xdp_fd: %s\n", strerror(-err));
			fprintf(stderr, "Failed to detach XDP program\n");
			exit(1);
		}
	} else {
		opts.old_prog_fd = prog_fd;
		err = bpf_xdp_attach(ifindex, -1, XDP_FLAGS_REPLACE, &opts);
		close(prog_fd);
		if (err < 0) {
			fprintf(stderr, "Error: bpf_set_link_xdp_fd_opts: %s\n", strerror(-err));
			/* Not an error if already replaced by someone else. */
			if (err != -EEXIST) {
				fprintf(stderr, "Failed to detach XDP program\n");
				exit(1);
			}
		}
	}
	exit(0);
}

static noreturn void usage(const char *progname)
{
	fprintf(stderr, "Usage: %s [--iface <iface>|--prog <prog_id>] [--mss4 <mss ipv4> --mss6 <mss ipv6> --wscale <wscale> --ttl <ttl>] [--ports <port1>,<port2>,...] [--single] [--tc]\n",
		progname);
	exit(1);
}

static unsigned long parse_arg_ul(const char *progname, const char *arg, unsigned long limit)
{
	unsigned long res;
	char *endptr;

	errno = 0;
	res = strtoul(arg, &endptr, 10);
	if (errno != 0 || *endptr != '\0' || arg[0] == '\0' || res > limit)
		usage(progname);

	return res;
}

static void parse_options(int argc, char *argv[], unsigned int *ifindex, __u32 *prog_id,
			  __u64 *tcpipopts, char **ports, bool *single, bool *tc)
{
	static struct option long_options[] = {
		{ "help", no_argument, NULL, 'h' },
		{ "iface", required_argument, NULL, 'i' },
		{ "prog", required_argument, NULL, 'x' },
		{ "mss4", required_argument, NULL, 4 },
		{ "mss6", required_argument, NULL, 6 },
		{ "wscale", required_argument, NULL, 'w' },
		{ "ttl", required_argument, NULL, 't' },
		{ "ports", required_argument, NULL, 'p' },
		{ "single", no_argument, NULL, 's' },
		{ "tc", no_argument, NULL, 'c' },
		{ NULL, 0, NULL, 0 },
	};
	unsigned long mss4, wscale, ttl;
	unsigned long long mss6;
	unsigned int tcpipopts_mask = 0;

	if (argc < 2)
		usage(argv[0]);

	*ifindex = 0;
	*prog_id = 0;
	*tcpipopts = 0;
	*ports = NULL;
	*single = false;

	while (true) {
		int opt;

		opt = getopt_long(argc, argv, "", long_options, NULL);
		if (opt == -1)
			break;

		switch (opt) {
		case 'h':
			usage(argv[0]);
			break;
		case 'i':
			*ifindex = if_nametoindex(optarg);
			if (*ifindex == 0)
				usage(argv[0]);
			break;
		case 'x':
			*prog_id = parse_arg_ul(argv[0], optarg, UINT32_MAX);
			if (*prog_id == 0)
				usage(argv[0]);
			break;
		case 4:
			mss4 = parse_arg_ul(argv[0], optarg, UINT16_MAX);
			tcpipopts_mask |= 1 << 0;
			break;
		case 6:
			mss6 = parse_arg_ul(argv[0], optarg, UINT16_MAX);
			tcpipopts_mask |= 1 << 1;
			break;
		case 'w':
			wscale = parse_arg_ul(argv[0], optarg, 14);
			tcpipopts_mask |= 1 << 2;
			break;
		case 't':
			ttl = parse_arg_ul(argv[0], optarg, UINT8_MAX);
			tcpipopts_mask |= 1 << 3;
			break;
		case 'p':
			*ports = optarg;
			break;
		case 's':
			*single = true;
			break;
		case 'c':
			*tc = true;
			break;
		default:
			usage(argv[0]);
		}
	}
	if (optind < argc)
		usage(argv[0]);

	if (tcpipopts_mask == 0xf) {
		if (mss4 == 0 || mss6 == 0 || wscale == 0 || ttl == 0)
			usage(argv[0]);
		*tcpipopts = (mss6 << 32) | (ttl << 24) | (wscale << 16) | mss4;
	} else if (tcpipopts_mask != 0) {
		usage(argv[0]);
	}

	if (*ifindex != 0 && *prog_id != 0)
		usage(argv[0]);
	if (*ifindex == 0 && *prog_id == 0)
		usage(argv[0]);
}

static int syncookie_attach(const char *argv0, unsigned int ifindex, bool tc)
{
	struct bpf_prog_info info = {};
	__u32 info_len = sizeof(info);
	char xdp_filename[PATH_MAX];
	struct bpf_program *prog;
	struct bpf_object *obj;
	int prog_fd;
	int err;

	snprintf(xdp_filename, sizeof(xdp_filename), "%s_kern.o", argv0);
	obj = bpf_object__open_file(xdp_filename, NULL);
	err = libbpf_get_error(obj);
	if (err < 0) {
		fprintf(stderr, "Error: bpf_object__open_file: %s\n", strerror(-err));
		return err;
	}

	err = bpf_object__load(obj);
	if (err < 0) {
		fprintf(stderr, "Error: bpf_object__open_file: %s\n", strerror(-err));
		return err;
	}

	prog = bpf_object__find_program_by_name(obj, tc ? "syncookie_tc" : "syncookie_xdp");
	if (!prog) {
		fprintf(stderr, "Error: bpf_object__find_program_by_name: program was not found\n");
		return -ENOENT;
	}

	prog_fd = bpf_program__fd(prog);

	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
	if (err < 0) {
		fprintf(stderr, "Error: bpf_obj_get_info_by_fd: %s\n", strerror(-err));
		goto out;
	}
	attached_tc = tc;
	attached_prog_id = info.id;
	signal(SIGINT, cleanup);
	signal(SIGTERM, cleanup);
	if (tc) {
		LIBBPF_OPTS(bpf_tc_hook, hook,
			    .ifindex = ifindex,
			    .attach_point = BPF_TC_INGRESS);
		LIBBPF_OPTS(bpf_tc_opts, opts,
			    .handle = 1,
			    .priority = 1,
			    .prog_fd = prog_fd);

		err = bpf_tc_hook_create(&hook);
		if (err < 0) {
			fprintf(stderr, "Error: bpf_tc_hook_create: %s\n",
				strerror(-err));
			goto fail;
		}
		err = bpf_tc_attach(&hook, &opts);
		if (err < 0) {
			fprintf(stderr, "Error: bpf_tc_attach: %s\n",
				strerror(-err));
			goto fail;
		}

	} else {
		err = bpf_xdp_attach(ifindex, prog_fd,
				     XDP_FLAGS_UPDATE_IF_NOEXIST, NULL);
		if (err < 0) {
			fprintf(stderr, "Error: bpf_set_link_xdp_fd: %s\n",
				strerror(-err));
			goto fail;
		}
	}
	err = 0;
out:
	bpf_object__close(obj);
	return err;
fail:
	signal(SIGINT, SIG_DFL);
	signal(SIGTERM, SIG_DFL);
	attached_prog_id = 0;
	goto out;
}

static int syncookie_open_bpf_maps(__u32 prog_id, int *values_map_fd, int *ports_map_fd)
{
	struct bpf_prog_info prog_info;
	__u32 map_ids[8];
	__u32 info_len;
	int prog_fd;
	int err;
	int i;

	*values_map_fd = -1;
	*ports_map_fd = -1;

	prog_fd = bpf_prog_get_fd_by_id(prog_id);
	if (prog_fd < 0) {
		fprintf(stderr, "Error: bpf_prog_get_fd_by_id: %s\n", strerror(-prog_fd));
		return prog_fd;
	}

	prog_info = (struct bpf_prog_info) {
		.nr_map_ids = 8,
		.map_ids = (__u64)(unsigned long)map_ids,
	};
	info_len = sizeof(prog_info);

	err = bpf_obj_get_info_by_fd(prog_fd, &prog_info, &info_len);
	if (err != 0) {
		fprintf(stderr, "Error: bpf_obj_get_info_by_fd: %s\n", strerror(-err));
		goto out;
	}

	if (prog_info.nr_map_ids < 2) {
		fprintf(stderr, "Error: Found %u BPF maps, expected at least 2\n",
			prog_info.nr_map_ids);
		err = -ENOENT;
		goto out;
	}

	for (i = 0; i < prog_info.nr_map_ids; i++) {
		struct bpf_map_info map_info = {};
		int map_fd;

		err = bpf_map_get_fd_by_id(map_ids[i]);
		if (err < 0) {
			fprintf(stderr, "Error: bpf_map_get_fd_by_id: %s\n", strerror(-err));
			goto err_close_map_fds;
		}
		map_fd = err;

		info_len = sizeof(map_info);
		err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
		if (err != 0) {
			fprintf(stderr, "Error: bpf_obj_get_info_by_fd: %s\n", strerror(-err));
			close(map_fd);
			goto err_close_map_fds;
		}
		if (strcmp(map_info.name, "values") == 0) {
			*values_map_fd = map_fd;
			continue;
		}
		if (strcmp(map_info.name, "allowed_ports") == 0) {
			*ports_map_fd = map_fd;
			continue;
		}
		close(map_fd);
	}

	if (*values_map_fd != -1 && *ports_map_fd != -1) {
		err = 0;
		goto out;
	}

	err = -ENOENT;

err_close_map_fds:
	if (*values_map_fd != -1)
		close(*values_map_fd);
	if (*ports_map_fd != -1)
		close(*ports_map_fd);
	*values_map_fd = -1;
	*ports_map_fd = -1;

out:
	close(prog_fd);
	return err;
}

int main(int argc, char *argv[])
{
	int values_map_fd, ports_map_fd;
	__u64 tcpipopts;
	bool firstiter;
	__u64 prevcnt;
	__u32 prog_id;
	char *ports;
	bool single;
	int err = 0;
	bool tc;

	parse_options(argc, argv, &ifindex, &prog_id, &tcpipopts, &ports,
		      &single, &tc);

	if (prog_id == 0) {
		if (!tc) {
			err = bpf_xdp_query_id(ifindex, 0, &prog_id);
			if (err < 0) {
				fprintf(stderr, "Error: bpf_get_link_xdp_id: %s\n",
					strerror(-err));
				goto out;
			}
		}
		if (prog_id == 0) {
			err = syncookie_attach(argv[0], ifindex, tc);
			if (err < 0)
				goto out;
			prog_id = attached_prog_id;
		}
	}

	err = syncookie_open_bpf_maps(prog_id, &values_map_fd, &ports_map_fd);
	if (err < 0)
		goto out;

	if (ports) {
		__u16 port_last = 0;
		__u32 port_idx = 0;
		char *p = ports;

		fprintf(stderr, "Replacing allowed ports\n");

		while (p && *p != '\0') {
			char *token = strsep(&p, ",");
			__u16 port;

			port = parse_arg_ul(argv[0], token, UINT16_MAX);
			err = bpf_map_update_elem(ports_map_fd, &port_idx, &port, BPF_ANY);
			if (err != 0) {
				fprintf(stderr, "Error: bpf_map_update_elem: %s\n", strerror(-err));
				fprintf(stderr, "Failed to add port %u (index %u)\n",
					port, port_idx);
				goto out_close_maps;
			}
			fprintf(stderr, "Added port %u\n", port);
			port_idx++;
		}
		err = bpf_map_update_elem(ports_map_fd, &port_idx, &port_last, BPF_ANY);
		if (err != 0) {
			fprintf(stderr, "Error: bpf_map_update_elem: %s\n", strerror(-err));
			fprintf(stderr, "Failed to add the terminator value 0 (index %u)\n",
				port_idx);
			goto out_close_maps;
		}
	}

	if (tcpipopts) {
		__u32 key = 0;

		fprintf(stderr, "Replacing TCP/IP options\n");

		err = bpf_map_update_elem(values_map_fd, &key, &tcpipopts, BPF_ANY);
		if (err != 0) {
			fprintf(stderr, "Error: bpf_map_update_elem: %s\n", strerror(-err));
			goto out_close_maps;
		}
	}

	if ((ports || tcpipopts) && attached_prog_id == 0 && !single)
		goto out_close_maps;

	prevcnt = 0;
	firstiter = true;
	while (true) {
		__u32 key = 1;
		__u64 value;

		err = bpf_map_lookup_elem(values_map_fd, &key, &value);
		if (err != 0) {
			fprintf(stderr, "Error: bpf_map_lookup_elem: %s\n", strerror(-err));
			goto out_close_maps;
		}
		if (firstiter) {
			prevcnt = value;
			firstiter = false;
		}
		if (single) {
			printf("Total SYNACKs generated: %llu\n", value);
			break;
		}
		printf("SYNACKs generated: %llu (total %llu)\n", value - prevcnt, value);
		prevcnt = value;
		sleep(1);
	}

out_close_maps:
	close(values_map_fd);
	close(ports_map_fd);
out:
	return err == 0 ? 0 : 1;
}
