// SPDX-License-Identifier: GPL-2.0
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
#include <limits.h>
#include <assert.h>

#include <sys/socket.h>
#include <sys/resource.h>

#include <linux/filter.h>
#include <linux/bpf.h>
#include <linux/if_alg.h>

#include <bpf/bpf.h>

#include "../../../include/linux/filter.h"

static struct bpf_insn prog[BPF_MAXINSNS];

static void bpf_gen_imm_prog(unsigned int insns, int fd_map)
{
	int i;

	srand(time(NULL));
	for (i = 0; i < insns; i++)
		prog[i] = BPF_ALU64_IMM(BPF_MOV, i % BPF_REG_10, rand());
	prog[i - 1] = BPF_EXIT_INSN();
}

static void bpf_gen_map_prog(unsigned int insns, int fd_map)
{
	int i, j = 0;

	for (i = 0; i + 1 < insns; i += 2) {
		struct bpf_insn tmp[] = {
			BPF_LD_MAP_FD(j++ % BPF_REG_10, fd_map)
		};

		memcpy(&prog[i], tmp, sizeof(tmp));
	}
	if (insns % 2 == 0)
		prog[insns - 2] = BPF_ALU64_IMM(BPF_MOV, i % BPF_REG_10, 42);
	prog[insns - 1] = BPF_EXIT_INSN();
}

static int bpf_try_load_prog(int insns, int fd_map,
			     void (*bpf_filler)(unsigned int insns,
						int fd_map))
{
	int fd_prog;

	bpf_filler(insns, fd_map);
	fd_prog = bpf_load_program(BPF_PROG_TYPE_SCHED_CLS, prog, insns, "", 0,
				   NULL, 0);
	assert(fd_prog > 0);
	if (fd_map > 0)
		bpf_filler(insns, 0);
	return fd_prog;
}

static int __hex2bin(char ch)
{
	if ((ch >= '0') && (ch <= '9'))
		return ch - '0';
	ch = tolower(ch);
	if ((ch >= 'a') && (ch <= 'f'))
		return ch - 'a' + 10;
	return -1;
}

static int hex2bin(uint8_t *dst, const char *src, size_t count)
{
	while (count--) {
		int hi = __hex2bin(*src++);
		int lo = __hex2bin(*src++);

		if ((hi < 0) || (lo < 0))
			return -1;
		*dst++ = (hi << 4) | lo;
	}
	return 0;
}

static void tag_from_fdinfo(int fd_prog, uint8_t *tag, uint32_t len)
{
	const int prefix_len = sizeof("prog_tag:\t") - 1;
	char buff[256];
	int ret = -1;
	FILE *fp;

	snprintf(buff, sizeof(buff), "/proc/%d/fdinfo/%d", getpid(),
		 fd_prog);
	fp = fopen(buff, "r");
	assert(fp);

	while (fgets(buff, sizeof(buff), fp)) {
		if (strncmp(buff, "prog_tag:\t", prefix_len))
			continue;
		ret = hex2bin(tag, buff + prefix_len, len);
		break;
	}

	fclose(fp);
	assert(!ret);
}

static void tag_from_alg(int insns, uint8_t *tag, uint32_t len)
{
	static const struct sockaddr_alg alg = {
		.salg_family	= AF_ALG,
		.salg_type	= "hash",
		.salg_name	= "sha1",
	};
	int fd_base, fd_alg, ret;
	ssize_t size;

	fd_base = socket(AF_ALG, SOCK_SEQPACKET, 0);
	assert(fd_base > 0);

	ret = bind(fd_base, (struct sockaddr *)&alg, sizeof(alg));
	assert(!ret);

	fd_alg = accept(fd_base, NULL, 0);
	assert(fd_alg > 0);

	insns *= sizeof(struct bpf_insn);
	size = write(fd_alg, prog, insns);
	assert(size == insns);

	size = read(fd_alg, tag, len);
	assert(size == len);

	close(fd_alg);
	close(fd_base);
}

static void tag_dump(const char *prefix, uint8_t *tag, uint32_t len)
{
	int i;

	printf("%s", prefix);
	for (i = 0; i < len; i++)
		printf("%02x", tag[i]);
	printf("\n");
}

static void tag_exit_report(int insns, int fd_map, uint8_t *ftag,
			    uint8_t *atag, uint32_t len)
{
	printf("Program tag mismatch for %d insns%s!\n", insns,
	       fd_map < 0 ? "" : " with map");

	tag_dump("  fdinfo result: ", ftag, len);
	tag_dump("  af_alg result: ", atag, len);
	exit(1);
}

static void do_test(uint32_t *tests, int start_insns, int fd_map,
		    void (*bpf_filler)(unsigned int insns, int fd))
{
	int i, fd_prog;

	for (i = start_insns; i <= BPF_MAXINSNS; i++) {
		uint8_t ftag[8], atag[sizeof(ftag)];

		fd_prog = bpf_try_load_prog(i, fd_map, bpf_filler);
		tag_from_fdinfo(fd_prog, ftag, sizeof(ftag));
		tag_from_alg(i, atag, sizeof(atag));
		if (memcmp(ftag, atag, sizeof(ftag)))
			tag_exit_report(i, fd_map, ftag, atag, sizeof(ftag));

		close(fd_prog);
		sched_yield();
		(*tests)++;
	}
}

int main(void)
{
	struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
	uint32_t tests = 0;
	int i, fd_map;

	setrlimit(RLIMIT_MEMLOCK, &rinf);
	fd_map = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int),
				sizeof(int), 1, BPF_F_NO_PREALLOC);
	assert(fd_map > 0);

	for (i = 0; i < 5; i++) {
		do_test(&tests, 2, -1,     bpf_gen_imm_prog);
		do_test(&tests, 3, fd_map, bpf_gen_map_prog);
	}

	printf("test_tag: OK (%u tests)\n", tests);
	close(fd_map);
	return 0;
}
