// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 */

#ifdef DEBUG

#include <linux/jiffies.h>

static const struct {
	bool result;
	unsigned int msec_to_sleep_before;
} expected_results[] __initconst = {
	[0 ... PACKETS_BURSTABLE - 1] = { true, 0 },
	[PACKETS_BURSTABLE] = { false, 0 },
	[PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND },
	[PACKETS_BURSTABLE + 2] = { false, 0 },
	[PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
	[PACKETS_BURSTABLE + 4] = { true, 0 },
	[PACKETS_BURSTABLE + 5] = { false, 0 }
};

static __init unsigned int maximum_jiffies_at_index(int index)
{
	unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3;
	int i;

	for (i = 0; i <= index; ++i)
		total_msecs += expected_results[i].msec_to_sleep_before;
	return msecs_to_jiffies(total_msecs);
}

static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
			       struct sk_buff *skb6, struct ipv6hdr *hdr6,
			       int *test)
{
	unsigned long loop_start_time;
	int i;

	wg_ratelimiter_gc_entries(NULL);
	rcu_barrier();
	loop_start_time = jiffies;

	for (i = 0; i < ARRAY_SIZE(expected_results); ++i) {
		if (expected_results[i].msec_to_sleep_before)
			msleep(expected_results[i].msec_to_sleep_before);

		if (time_is_before_jiffies(loop_start_time +
					   maximum_jiffies_at_index(i)))
			return -ETIMEDOUT;
		if (wg_ratelimiter_allow(skb4, &init_net) !=
					expected_results[i].result)
			return -EXFULL;
		++(*test);

		hdr4->saddr = htonl(ntohl(hdr4->saddr) + i + 1);
		if (time_is_before_jiffies(loop_start_time +
					   maximum_jiffies_at_index(i)))
			return -ETIMEDOUT;
		if (!wg_ratelimiter_allow(skb4, &init_net))
			return -EXFULL;
		++(*test);

		hdr4->saddr = htonl(ntohl(hdr4->saddr) - i - 1);

#if IS_ENABLED(CONFIG_IPV6)
		hdr6->saddr.in6_u.u6_addr32[2] = htonl(i);
		hdr6->saddr.in6_u.u6_addr32[3] = htonl(i);
		if (time_is_before_jiffies(loop_start_time +
					   maximum_jiffies_at_index(i)))
			return -ETIMEDOUT;
		if (wg_ratelimiter_allow(skb6, &init_net) !=
					expected_results[i].result)
			return -EXFULL;
		++(*test);

		hdr6->saddr.in6_u.u6_addr32[0] =
			htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) + i + 1);
		if (time_is_before_jiffies(loop_start_time +
					   maximum_jiffies_at_index(i)))
			return -ETIMEDOUT;
		if (!wg_ratelimiter_allow(skb6, &init_net))
			return -EXFULL;
		++(*test);

		hdr6->saddr.in6_u.u6_addr32[0] =
			htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) - i - 1);

		if (time_is_before_jiffies(loop_start_time +
					   maximum_jiffies_at_index(i)))
			return -ETIMEDOUT;
#endif
	}
	return 0;
}

static __init int capacity_test(struct sk_buff *skb4, struct iphdr *hdr4,
				int *test)
{
	int i;

	wg_ratelimiter_gc_entries(NULL);
	rcu_barrier();

	if (atomic_read(&total_entries))
		return -EXFULL;
	++(*test);

	for (i = 0; i <= max_entries; ++i) {
		hdr4->saddr = htonl(i);
		if (wg_ratelimiter_allow(skb4, &init_net) != (i != max_entries))
			return -EXFULL;
		++(*test);
	}
	return 0;
}

bool __init wg_ratelimiter_selftest(void)
{
	enum { TRIALS_BEFORE_GIVING_UP = 5000 };
	bool success = false;
	int test = 0, trials;
	struct sk_buff *skb4, *skb6 = NULL;
	struct iphdr *hdr4;
	struct ipv6hdr *hdr6 = NULL;

	if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
		return true;

	BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0);

	if (wg_ratelimiter_init())
		goto out;
	++test;
	if (wg_ratelimiter_init()) {
		wg_ratelimiter_uninit();
		goto out;
	}
	++test;
	if (wg_ratelimiter_init()) {
		wg_ratelimiter_uninit();
		wg_ratelimiter_uninit();
		goto out;
	}
	++test;

	skb4 = alloc_skb(sizeof(struct iphdr), GFP_KERNEL);
	if (unlikely(!skb4))
		goto err_nofree;
	skb4->protocol = htons(ETH_P_IP);
	hdr4 = (struct iphdr *)skb_put(skb4, sizeof(*hdr4));
	hdr4->saddr = htonl(8182);
	skb_reset_network_header(skb4);
	++test;

#if IS_ENABLED(CONFIG_IPV6)
	skb6 = alloc_skb(sizeof(struct ipv6hdr), GFP_KERNEL);
	if (unlikely(!skb6)) {
		kfree_skb(skb4);
		goto err_nofree;
	}
	skb6->protocol = htons(ETH_P_IPV6);
	hdr6 = (struct ipv6hdr *)skb_put(skb6, sizeof(*hdr6));
	hdr6->saddr.in6_u.u6_addr32[0] = htonl(1212);
	hdr6->saddr.in6_u.u6_addr32[1] = htonl(289188);
	skb_reset_network_header(skb6);
	++test;
#endif

	for (trials = TRIALS_BEFORE_GIVING_UP;;) {
		int test_count = 0, ret;

		ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count);
		if (ret == -ETIMEDOUT) {
			if (!trials--) {
				test += test_count;
				goto err;
			}
			msleep(500);
			continue;
		} else if (ret < 0) {
			test += test_count;
			goto err;
		} else {
			test += test_count;
			break;
		}
	}

	for (trials = TRIALS_BEFORE_GIVING_UP;;) {
		int test_count = 0;

		if (capacity_test(skb4, hdr4, &test_count) < 0) {
			if (!trials--) {
				test += test_count;
				goto err;
			}
			msleep(50);
			continue;
		}
		test += test_count;
		break;
	}

	success = true;

err:
	kfree_skb(skb4);
#if IS_ENABLED(CONFIG_IPV6)
	kfree_skb(skb6);
#endif
err_nofree:
	wg_ratelimiter_uninit();
	wg_ratelimiter_uninit();
	wg_ratelimiter_uninit();
	/* Uninit one extra time to check underflow detection. */
	wg_ratelimiter_uninit();
out:
	if (success)
		pr_info("ratelimiter self-tests: pass\n");
	else
		pr_err("ratelimiter self-test %d: FAIL\n", test);

	return success;
}
#endif
