// 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; IS_ENABLED(DEBUG_RATELIMITER_TIMINGS);) {
		int test_count = 0, ret;

		ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count);
		if (ret == -ETIMEDOUT) {
			if (!trials--) {
				test += test_count;
				goto err;
			}
			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;
			}
			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
