// SPDX-License-Identifier: GPL-2.0

#include <stddef.h>
#include <linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>

#define MAX_ADJST_OFFSET 256
#define MAX_PAYLOAD_LEN 5000
#define MAX_HDR_LEN 64

extern int bpf_xdp_pull_data(struct xdp_md *xdp, __u32 len) __ksym __weak;

enum {
	XDP_MODE = 0,
	XDP_PORT = 1,
	XDP_ADJST_OFFSET = 2,
	XDP_ADJST_TAG = 3,
} xdp_map_setup_keys;

enum {
	XDP_MODE_PASS = 0,
	XDP_MODE_DROP = 1,
	XDP_MODE_TX = 2,
	XDP_MODE_TAIL_ADJST = 3,
	XDP_MODE_HEAD_ADJST = 4,
} xdp_map_modes;

enum {
	STATS_RX = 0,
	STATS_PASS = 1,
	STATS_DROP = 2,
	STATS_TX = 3,
	STATS_ABORT = 4,
} xdp_stats;

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 5);
	__type(key, __u32);
	__type(value, __s32);
} map_xdp_setup SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 5);
	__type(key, __u32);
	__type(value, __u64);
} map_xdp_stats SEC(".maps");

static __u32 min(__u32 a, __u32 b)
{
	return a < b ? a : b;
}

static void record_stats(struct xdp_md *ctx, __u32 stat_type)
{
	__u64 *count;

	count = bpf_map_lookup_elem(&map_xdp_stats, &stat_type);

	if (count)
		__sync_fetch_and_add(count, 1);
}

static struct udphdr *filter_udphdr(struct xdp_md *ctx, __u16 port)
{
	struct udphdr *udph = NULL;
	void *data, *data_end;
	struct ethhdr *eth;
	int err;

	err = bpf_xdp_pull_data(ctx, sizeof(*eth));
	if (err)
		return NULL;

	data_end = (void *)(long)ctx->data_end;
	data = eth = (void *)(long)ctx->data;

	if (data + sizeof(*eth) > data_end)
		return NULL;

	if (eth->h_proto == bpf_htons(ETH_P_IP)) {
		struct iphdr *iph;

		err = bpf_xdp_pull_data(ctx, sizeof(*eth) + sizeof(*iph) +
					     sizeof(*udph));
		if (err)
			return NULL;

		data_end = (void *)(long)ctx->data_end;
		data = (void *)(long)ctx->data;

		iph = data + sizeof(*eth);

		if (iph + 1 > (struct iphdr *)data_end ||
		    iph->protocol != IPPROTO_UDP)
			return NULL;

		udph = data + sizeof(*iph) + sizeof(*eth);
	} else if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {
		struct ipv6hdr *ipv6h;

		err = bpf_xdp_pull_data(ctx, sizeof(*eth) + sizeof(*ipv6h) +
					     sizeof(*udph));
		if (err)
			return NULL;

		data_end = (void *)(long)ctx->data_end;
		data = (void *)(long)ctx->data;

		ipv6h = data + sizeof(*eth);

		if (ipv6h + 1 > (struct ipv6hdr *)data_end ||
		    ipv6h->nexthdr != IPPROTO_UDP)
			return NULL;

		udph = data + sizeof(*ipv6h) + sizeof(*eth);
	} else {
		return NULL;
	}

	if (udph + 1 > (struct udphdr *)data_end)
		return NULL;

	if (udph->dest != bpf_htons(port))
		return NULL;

	record_stats(ctx, STATS_RX);

	return udph;
}

static int xdp_mode_pass(struct xdp_md *ctx, __u16 port)
{
	struct udphdr *udph = NULL;

	udph = filter_udphdr(ctx, port);
	if (!udph)
		return XDP_PASS;

	record_stats(ctx, STATS_PASS);

	return XDP_PASS;
}

static int xdp_mode_drop_handler(struct xdp_md *ctx, __u16 port)
{
	struct udphdr *udph = NULL;

	udph = filter_udphdr(ctx, port);
	if (!udph)
		return XDP_PASS;

	record_stats(ctx, STATS_DROP);

	return XDP_DROP;
}

static void swap_machdr(void *data)
{
	struct ethhdr *eth = data;
	__u8 tmp_mac[ETH_ALEN];

	__builtin_memcpy(tmp_mac, eth->h_source, ETH_ALEN);
	__builtin_memcpy(eth->h_source, eth->h_dest, ETH_ALEN);
	__builtin_memcpy(eth->h_dest, tmp_mac, ETH_ALEN);
}

static int xdp_mode_tx_handler(struct xdp_md *ctx, __u16 port)
{
	struct udphdr *udph = NULL;
	void *data, *data_end;
	struct ethhdr *eth;
	int err;

	err = bpf_xdp_pull_data(ctx, sizeof(*eth));
	if (err)
		return XDP_PASS;

	data_end = (void *)(long)ctx->data_end;
	data = eth = (void *)(long)ctx->data;

	if (data + sizeof(*eth) > data_end)
		return XDP_PASS;

	if (eth->h_proto == bpf_htons(ETH_P_IP)) {
		struct iphdr *iph;
		__be32 tmp_ip;

		err = bpf_xdp_pull_data(ctx, sizeof(*eth) + sizeof(*iph) +
					     sizeof(*udph));
		if (err)
			return XDP_PASS;

		data_end = (void *)(long)ctx->data_end;
		data = (void *)(long)ctx->data;

		iph = data + sizeof(*eth);

		if (iph + 1 > (struct iphdr *)data_end ||
		    iph->protocol != IPPROTO_UDP)
			return XDP_PASS;

		udph = data + sizeof(*iph) + sizeof(*eth);

		if (udph + 1 > (struct udphdr *)data_end)
			return XDP_PASS;
		if (udph->dest != bpf_htons(port))
			return XDP_PASS;

		record_stats(ctx, STATS_RX);
		eth = data;
		swap_machdr((void *)eth);

		tmp_ip = iph->saddr;
		iph->saddr = iph->daddr;
		iph->daddr = tmp_ip;

		record_stats(ctx, STATS_TX);

		return XDP_TX;

	} else if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {
		struct in6_addr tmp_ipv6;
		struct ipv6hdr *ipv6h;

		err = bpf_xdp_pull_data(ctx, sizeof(*eth) + sizeof(*ipv6h) +
					     sizeof(*udph));
		if (err)
			return XDP_PASS;

		data_end = (void *)(long)ctx->data_end;
		data = (void *)(long)ctx->data;

		ipv6h = data + sizeof(*eth);

		if (ipv6h + 1 > (struct ipv6hdr *)data_end ||
		    ipv6h->nexthdr != IPPROTO_UDP)
			return XDP_PASS;

		udph = data + sizeof(*ipv6h) + sizeof(*eth);

		if (udph + 1 > (struct udphdr *)data_end)
			return XDP_PASS;
		if (udph->dest != bpf_htons(port))
			return XDP_PASS;

		record_stats(ctx, STATS_RX);
		eth = data;
		swap_machdr((void *)eth);

		__builtin_memcpy(&tmp_ipv6, &ipv6h->saddr, sizeof(tmp_ipv6));
		__builtin_memcpy(&ipv6h->saddr, &ipv6h->daddr,
				 sizeof(tmp_ipv6));
		__builtin_memcpy(&ipv6h->daddr, &tmp_ipv6, sizeof(tmp_ipv6));

		record_stats(ctx, STATS_TX);

		return XDP_TX;
	}

	return XDP_PASS;
}

static __always_inline __u16 csum_fold_helper(__u32 csum)
{
	csum = (csum & 0xffff) + (csum >> 16);
	return ~((csum & 0xffff) + (csum >> 16));
}

static __always_inline __u16 csum_fold_udp_helper(__u32 csum)
{
	return csum_fold_helper(csum) ? : 0xffff;
}

static void *update_pkt(struct xdp_md *ctx, __s16 offset, __u32 *udp_csum)
{
	void *data_end = (void *)(long)ctx->data_end;
	void *data = (void *)(long)ctx->data;
	struct udphdr *udph = NULL;
	struct ethhdr *eth = data;
	__u32 len, len_new;

	if (data + sizeof(*eth) > data_end)
		return NULL;

	if (eth->h_proto == bpf_htons(ETH_P_IP)) {
		struct iphdr *iph = data + sizeof(*eth);

		if (iph + 1 > (struct iphdr *)data_end)
			return NULL;

		udph = (void *)eth + sizeof(*iph) + sizeof(*eth);
		if (!udph || udph + 1 > (struct udphdr *)data_end)
			return NULL;

		len = iph->tot_len;
		len_new = bpf_htons(bpf_ntohs(len) + offset);
		iph->tot_len = len_new;
		iph->check = csum_fold_helper(
			bpf_csum_diff(&len, sizeof(len), &len_new,
				      sizeof(len_new), ~((__u32)iph->check)));
	} else if (eth->h_proto  == bpf_htons(ETH_P_IPV6)) {
		struct ipv6hdr *ipv6h = data + sizeof(*eth);

		if (ipv6h + 1 > (struct ipv6hdr *)data_end)
			return NULL;

		udph = (void *)eth + sizeof(*ipv6h) + sizeof(*eth);
		if (!udph || udph + 1 > (struct udphdr *)data_end)
			return NULL;

		len = ipv6h->payload_len;
		len_new = bpf_htons(bpf_ntohs(len) + offset);
		ipv6h->payload_len = len_new;
	} else {
		return NULL;
	}

	len = udph->len;
	len_new = bpf_htons(bpf_ntohs(len) + offset);

	*udp_csum = ~((__u32)udph->check);
	*udp_csum = bpf_csum_diff(&len, sizeof(len), &len_new,
				  sizeof(len_new), *udp_csum);
	*udp_csum = bpf_csum_diff(&len, sizeof(len), &len_new,
				  sizeof(len_new), *udp_csum);

	udph->len = len_new;

	return udph;
}

static int xdp_adjst_tail_shrnk_data(struct xdp_md *ctx, __u16 offset,
				     unsigned long hdr_len)
{
	char tmp_buff[MAX_ADJST_OFFSET];
	__u32 buff_pos, udp_csum = 0;
	struct udphdr *udph = NULL;
	__u32 buff_len;

	udph = update_pkt(ctx, 0 - offset, &udp_csum);
	if (!udph)
		return -1;

	buff_len = bpf_xdp_get_buff_len(ctx);

	offset = (offset & 0x1ff) >= MAX_ADJST_OFFSET ? MAX_ADJST_OFFSET :
				     offset & 0xff;
	if (offset == 0)
		return -1;

	/* Make sure we have enough data to avoid eating the header */
	if (buff_len - offset < hdr_len)
		return -1;

	buff_pos = buff_len - offset;
	if (bpf_xdp_load_bytes(ctx, buff_pos, tmp_buff, offset) < 0)
		return -1;

	udp_csum = bpf_csum_diff((__be32 *)tmp_buff, offset, 0, 0, udp_csum);
	udph->check = (__u16)csum_fold_udp_helper(udp_csum);

	if (bpf_xdp_adjust_tail(ctx, 0 - offset) < 0)
		return -1;

	return 0;
}

static int xdp_adjst_tail_grow_data(struct xdp_md *ctx, __u16 offset)
{
	char tmp_buff[MAX_ADJST_OFFSET];
	__u32 buff_pos, udp_csum = 0;
	__u32 buff_len, hdr_len, key;
	struct udphdr *udph;
	__s32 *val;
	__u8 tag;

	/* Proceed to update the packet headers before attempting to adjuste
	 * the tail. Once the tail is adjusted we lose access to the offset
	 * amount of data at the end of the packet which is crucial to update
	 * the checksum.
	 * Since any failure beyond this would abort the packet, we should
	 * not worry about passing a packet up the stack with wrong headers
	 */
	udph = update_pkt(ctx, offset, &udp_csum);
	if (!udph)
		return -1;

	key = XDP_ADJST_TAG;
	val = bpf_map_lookup_elem(&map_xdp_setup, &key);
	if (!val)
		return -1;

	tag = (__u8)(*val);

	for (int i = 0; i < MAX_ADJST_OFFSET; i++)
		__builtin_memcpy(&tmp_buff[i], &tag, 1);

	offset = (offset & 0x1ff) >= MAX_ADJST_OFFSET ? MAX_ADJST_OFFSET :
				     offset & 0xff;
	if (offset == 0)
		return -1;

	udp_csum = bpf_csum_diff(0, 0, (__be32 *)tmp_buff, offset, udp_csum);
	udph->check = (__u16)csum_fold_udp_helper(udp_csum);

	buff_len = bpf_xdp_get_buff_len(ctx);

	if (bpf_xdp_adjust_tail(ctx, offset) < 0) {
		bpf_printk("Failed to adjust tail\n");
		return -1;
	}

	if (bpf_xdp_store_bytes(ctx, buff_len, tmp_buff, offset) < 0)
		return -1;

	return 0;
}

static int xdp_adjst_tail(struct xdp_md *ctx, __u16 port)
{
	struct udphdr *udph = NULL;
	__s32 *adjust_offset, *val;
	unsigned long hdr_len;
	void *offset_ptr;
	__u32 key;
	__u8 tag;
	int ret;

	udph = filter_udphdr(ctx, port);
	if (!udph)
		return XDP_PASS;

	hdr_len = (void *)udph - (void *)(long)ctx->data +
		  sizeof(struct udphdr);
	key = XDP_ADJST_OFFSET;
	adjust_offset = bpf_map_lookup_elem(&map_xdp_setup, &key);
	if (!adjust_offset)
		return XDP_PASS;

	if (*adjust_offset < 0)
		ret = xdp_adjst_tail_shrnk_data(ctx,
						(__u16)(0 - *adjust_offset),
						hdr_len);
	else
		ret = xdp_adjst_tail_grow_data(ctx, (__u16)(*adjust_offset));
	if (ret)
		goto abort_pkt;

	record_stats(ctx, STATS_PASS);
	return XDP_PASS;

abort_pkt:
	record_stats(ctx, STATS_ABORT);
	return XDP_ABORTED;
}

static int xdp_adjst_head_shrnk_data(struct xdp_md *ctx, __u64 hdr_len,
				     __u32 offset)
{
	char tmp_buff[MAX_ADJST_OFFSET];
	struct udphdr *udph;
	void *offset_ptr;
	__u32 udp_csum = 0;

	/* Update the length information in the IP and UDP headers before
	 * adjusting the headroom. This simplifies accessing the relevant
	 * fields in the IP and UDP headers for fragmented packets. Any
	 * failure beyond this point will result in the packet being aborted,
	 * so we don't need to worry about incorrect length information for
	 * passed packets.
	 */
	udph = update_pkt(ctx, (__s16)(0 - offset), &udp_csum);
	if (!udph)
		return -1;

	offset = (offset & 0x1ff) >= MAX_ADJST_OFFSET ? MAX_ADJST_OFFSET :
				     offset & 0xff;
	if (offset == 0)
		return -1;

	if (bpf_xdp_load_bytes(ctx, hdr_len, tmp_buff, offset) < 0)
		return -1;

	udp_csum = bpf_csum_diff((__be32 *)tmp_buff, offset, 0, 0, udp_csum);
	udph->check = (__u16)csum_fold_udp_helper(udp_csum);

	if (bpf_xdp_load_bytes(ctx, 0, tmp_buff, MAX_ADJST_OFFSET) < 0)
		return -1;

	if (bpf_xdp_adjust_head(ctx, offset) < 0)
		return -1;

	if (offset > MAX_ADJST_OFFSET)
		return -1;

	if (hdr_len > MAX_ADJST_OFFSET || hdr_len == 0)
		return -1;

	/* Added here to handle clang complain about negative value */
	hdr_len = hdr_len & 0xff;

	if (hdr_len == 0)
		return -1;

	if (bpf_xdp_store_bytes(ctx, 0, tmp_buff, hdr_len) < 0)
		return -1;

	return 0;
}

static int xdp_adjst_head_grow_data(struct xdp_md *ctx, __u64 hdr_len,
				    __u32 offset)
{
	char hdr_buff[MAX_HDR_LEN];
	char data_buff[MAX_ADJST_OFFSET];
	void *offset_ptr;
	__s32 *val;
	__u32 key;
	__u8 tag;
	__u32 udp_csum = 0;
	struct udphdr *udph;

	udph = update_pkt(ctx, (__s16)(offset), &udp_csum);
	if (!udph)
		return -1;

	key = XDP_ADJST_TAG;
	val = bpf_map_lookup_elem(&map_xdp_setup, &key);
	if (!val)
		return -1;

	tag = (__u8)(*val);
	for (int i = 0; i < MAX_ADJST_OFFSET; i++)
		__builtin_memcpy(&data_buff[i], &tag, 1);

	offset = (offset & 0x1ff) >= MAX_ADJST_OFFSET ? MAX_ADJST_OFFSET :
				     offset & 0xff;
	if (offset == 0)
		return -1;

	udp_csum = bpf_csum_diff(0, 0, (__be32 *)data_buff, offset, udp_csum);
	udph->check = (__u16)csum_fold_udp_helper(udp_csum);

	if (hdr_len > MAX_ADJST_OFFSET || hdr_len == 0)
		return -1;

	/* Added here to handle clang complain about negative value */
	hdr_len = hdr_len & 0xff;

	if (hdr_len == 0)
		return -1;

	if (bpf_xdp_load_bytes(ctx, 0, hdr_buff, hdr_len) < 0)
		return -1;

	if (offset > MAX_ADJST_OFFSET)
		return -1;

	if (bpf_xdp_adjust_head(ctx, 0 - offset) < 0)
		return -1;

	if (bpf_xdp_store_bytes(ctx, 0, hdr_buff, hdr_len) < 0)
		return -1;

	if (bpf_xdp_store_bytes(ctx, hdr_len, data_buff, offset) < 0)
		return -1;

	return 0;
}

static int xdp_head_adjst(struct xdp_md *ctx, __u16 port)
{
	struct udphdr *udph_ptr = NULL;
	__u32 key, size, hdr_len;
	__s32 *val;
	int res;

	/* Filter packets based on UDP port */
	udph_ptr = filter_udphdr(ctx, port);
	if (!udph_ptr)
		return XDP_PASS;

	hdr_len = (void *)udph_ptr - (void *)(long)ctx->data +
		  sizeof(struct udphdr);

	key = XDP_ADJST_OFFSET;
	val = bpf_map_lookup_elem(&map_xdp_setup, &key);
	if (!val)
		return XDP_PASS;

	switch (*val) {
	case -16:
	case 16:
		size = 16;
		break;
	case -32:
	case 32:
		size = 32;
		break;
	case -64:
	case 64:
		size = 64;
		break;
	case -128:
	case 128:
		size = 128;
		break;
	case -256:
	case 256:
		size = 256;
		break;
	default:
		bpf_printk("Invalid adjustment offset: %d\n", *val);
		goto abort;
	}

	if (*val < 0)
		res = xdp_adjst_head_grow_data(ctx, hdr_len, size);
	else
		res = xdp_adjst_head_shrnk_data(ctx, hdr_len, size);

	if (res)
		goto abort;

	record_stats(ctx, STATS_PASS);
	return XDP_PASS;

abort:
	record_stats(ctx, STATS_ABORT);
	return XDP_ABORTED;
}

static int xdp_prog_common(struct xdp_md *ctx)
{
	__u32 key, *port;
	__s32 *mode;

	key = XDP_MODE;
	mode = bpf_map_lookup_elem(&map_xdp_setup, &key);
	if (!mode)
		return XDP_PASS;

	key = XDP_PORT;
	port = bpf_map_lookup_elem(&map_xdp_setup, &key);
	if (!port)
		return XDP_PASS;

	switch (*mode) {
	case XDP_MODE_PASS:
		return xdp_mode_pass(ctx, (__u16)(*port));
	case XDP_MODE_DROP:
		return xdp_mode_drop_handler(ctx, (__u16)(*port));
	case XDP_MODE_TX:
		return xdp_mode_tx_handler(ctx, (__u16)(*port));
	case XDP_MODE_TAIL_ADJST:
		return xdp_adjst_tail(ctx, (__u16)(*port));
	case XDP_MODE_HEAD_ADJST:
		return xdp_head_adjst(ctx, (__u16)(*port));
	}

	/* Default action is to simple pass */
	return XDP_PASS;
}

SEC("xdp")
int xdp_prog(struct xdp_md *ctx)
{
	return xdp_prog_common(ctx);
}

SEC("xdp.frags")
int xdp_prog_frags(struct xdp_md *ctx)
{
	return xdp_prog_common(ctx);
}

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