// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2018 Facebook */

#include <stdlib.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/bpf.h>
#include <linux/types.h>
#include <linux/if_ether.h>

#include "bpf_endian.h"
#include "bpf_helpers.h"
#include "test_select_reuseport_common.h"

int _version SEC("version") = 1;

#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

struct bpf_map_def SEC("maps") outer_map = {
	.type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
	.key_size = sizeof(__u32),
	.value_size = sizeof(__u32),
	.max_entries = 1,
};

struct bpf_map_def SEC("maps") result_map = {
	.type = BPF_MAP_TYPE_ARRAY,
	.key_size = sizeof(__u32),
	.value_size = sizeof(__u32),
	.max_entries = NR_RESULTS,
};

struct bpf_map_def SEC("maps") tmp_index_ovr_map = {
	.type = BPF_MAP_TYPE_ARRAY,
	.key_size = sizeof(__u32),
	.value_size = sizeof(int),
	.max_entries = 1,
};

struct bpf_map_def SEC("maps") linum_map = {
	.type = BPF_MAP_TYPE_ARRAY,
	.key_size = sizeof(__u32),
	.value_size = sizeof(__u32),
	.max_entries = 1,
};

struct bpf_map_def SEC("maps") data_check_map = {
	.type = BPF_MAP_TYPE_ARRAY,
	.key_size = sizeof(__u32),
	.value_size = sizeof(struct data_check),
	.max_entries = 1,
};

#define GOTO_DONE(_result) ({			\
	result = (_result);			\
	linum = __LINE__;			\
	goto done;				\
})

SEC("select_by_skb_data")
int _select_by_skb_data(struct sk_reuseport_md *reuse_md)
{
	__u32 linum, index = 0, flags = 0, index_zero = 0;
	__u32 *result_cnt, *linum_value;
	struct data_check data_check = {};
	struct cmd *cmd, cmd_copy;
	void *data, *data_end;
	void *reuseport_array;
	enum result result;
	int *index_ovr;
	int err;

	data = reuse_md->data;
	data_end = reuse_md->data_end;
	data_check.len = reuse_md->len;
	data_check.eth_protocol = reuse_md->eth_protocol;
	data_check.ip_protocol = reuse_md->ip_protocol;
	data_check.hash = reuse_md->hash;
	data_check.bind_inany = reuse_md->bind_inany;
	if (data_check.eth_protocol == bpf_htons(ETH_P_IP)) {
		if (bpf_skb_load_bytes_relative(reuse_md,
						offsetof(struct iphdr, saddr),
						data_check.skb_addrs, 8,
						BPF_HDR_START_NET))
			GOTO_DONE(DROP_MISC);
	} else {
		if (bpf_skb_load_bytes_relative(reuse_md,
						offsetof(struct ipv6hdr, saddr),
						data_check.skb_addrs, 32,
						BPF_HDR_START_NET))
			GOTO_DONE(DROP_MISC);
	}

	/*
	 * The ip_protocol could be a compile time decision
	 * if the bpf_prog.o is dedicated to either TCP or
	 * UDP.
	 *
	 * Otherwise, reuse_md->ip_protocol or
	 * the protocol field in the iphdr can be used.
	 */
	if (data_check.ip_protocol == IPPROTO_TCP) {
		struct tcphdr *th = data;

		if (th + 1 > data_end)
			GOTO_DONE(DROP_MISC);

		data_check.skb_ports[0] = th->source;
		data_check.skb_ports[1] = th->dest;

		if ((th->doff << 2) + sizeof(*cmd) > data_check.len)
			GOTO_DONE(DROP_ERR_SKB_DATA);
		if (bpf_skb_load_bytes(reuse_md, th->doff << 2, &cmd_copy,
				       sizeof(cmd_copy)))
			GOTO_DONE(DROP_MISC);
		cmd = &cmd_copy;
	} else if (data_check.ip_protocol == IPPROTO_UDP) {
		struct udphdr *uh = data;

		if (uh + 1 > data_end)
			GOTO_DONE(DROP_MISC);

		data_check.skb_ports[0] = uh->source;
		data_check.skb_ports[1] = uh->dest;

		if (sizeof(struct udphdr) + sizeof(*cmd) > data_check.len)
			GOTO_DONE(DROP_ERR_SKB_DATA);
		if (data + sizeof(struct udphdr) + sizeof(*cmd) > data_end) {
			if (bpf_skb_load_bytes(reuse_md, sizeof(struct udphdr),
					       &cmd_copy, sizeof(cmd_copy)))
				GOTO_DONE(DROP_MISC);
			cmd = &cmd_copy;
		} else {
			cmd = data + sizeof(struct udphdr);
		}
	} else {
		GOTO_DONE(DROP_MISC);
	}

	reuseport_array = bpf_map_lookup_elem(&outer_map, &index_zero);
	if (!reuseport_array)
		GOTO_DONE(DROP_ERR_INNER_MAP);

	index = cmd->reuseport_index;
	index_ovr = bpf_map_lookup_elem(&tmp_index_ovr_map, &index_zero);
	if (!index_ovr)
		GOTO_DONE(DROP_MISC);

	if (*index_ovr != -1) {
		index = *index_ovr;
		*index_ovr = -1;
	}
	err = bpf_sk_select_reuseport(reuse_md, reuseport_array, &index,
				      flags);
	if (!err)
		GOTO_DONE(PASS);

	if (cmd->pass_on_failure)
		GOTO_DONE(PASS_ERR_SK_SELECT_REUSEPORT);
	else
		GOTO_DONE(DROP_ERR_SK_SELECT_REUSEPORT);

done:
	result_cnt = bpf_map_lookup_elem(&result_map, &result);
	if (!result_cnt)
		return SK_DROP;

	bpf_map_update_elem(&linum_map, &index_zero, &linum, BPF_ANY);
	bpf_map_update_elem(&data_check_map, &index_zero, &data_check, BPF_ANY);

	(*result_cnt)++;
	return result < PASS ? SK_DROP : SK_PASS;
}

char _license[] SEC("license") = "GPL";
