// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017 Facebook
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <linux/pkt_cls.h>
#include <linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <bpf/bpf_helpers.h>
#include "test_iptunnel_common.h"
#include <bpf/bpf_endian.h>

static __always_inline __u32 rol32(__u32 word, unsigned int shift)
{
	return (word << shift) | (word >> ((-shift) & 31));
}

/* copy paste of jhash from kernel sources to make sure llvm
 * can compile it into valid sequence of bpf instructions
 */
#define __jhash_mix(a, b, c)			\
{						\
	a -= c;  a ^= rol32(c, 4);  c += b;	\
	b -= a;  b ^= rol32(a, 6);  a += c;	\
	c -= b;  c ^= rol32(b, 8);  b += a;	\
	a -= c;  a ^= rol32(c, 16); c += b;	\
	b -= a;  b ^= rol32(a, 19); a += c;	\
	c -= b;  c ^= rol32(b, 4);  b += a;	\
}

#define __jhash_final(a, b, c)			\
{						\
	c ^= b; c -= rol32(b, 14);		\
	a ^= c; a -= rol32(c, 11);		\
	b ^= a; b -= rol32(a, 25);		\
	c ^= b; c -= rol32(b, 16);		\
	a ^= c; a -= rol32(c, 4);		\
	b ^= a; b -= rol32(a, 14);		\
	c ^= b; c -= rol32(b, 24);		\
}

#define JHASH_INITVAL		0xdeadbeef

typedef unsigned int u32;

static __noinline u32 jhash(const void *key, u32 length, u32 initval)
{
	u32 a, b, c;
	const unsigned char *k = key;

	a = b = c = JHASH_INITVAL + length + initval;

	while (length > 12) {
		a += *(u32 *)(k);
		b += *(u32 *)(k + 4);
		c += *(u32 *)(k + 8);
		__jhash_mix(a, b, c);
		length -= 12;
		k += 12;
	}
	switch (length) {
	case 12: c += (u32)k[11]<<24;
	case 11: c += (u32)k[10]<<16;
	case 10: c += (u32)k[9]<<8;
	case 9:  c += k[8];
	case 8:  b += (u32)k[7]<<24;
	case 7:  b += (u32)k[6]<<16;
	case 6:  b += (u32)k[5]<<8;
	case 5:  b += k[4];
	case 4:  a += (u32)k[3]<<24;
	case 3:  a += (u32)k[2]<<16;
	case 2:  a += (u32)k[1]<<8;
	case 1:  a += k[0];
		 __jhash_final(a, b, c);
	case 0: /* Nothing left to add */
		break;
	}

	return c;
}

static __noinline u32 __jhash_nwords(u32 a, u32 b, u32 c, u32 initval)
{
	a += initval;
	b += initval;
	c += initval;
	__jhash_final(a, b, c);
	return c;
}

static __noinline u32 jhash_2words(u32 a, u32 b, u32 initval)
{
	return __jhash_nwords(a, b, 0, initval + JHASH_INITVAL + (2 << 2));
}

#define PCKT_FRAGMENTED 65343
#define IPV4_HDR_LEN_NO_OPT 20
#define IPV4_PLUS_ICMP_HDR 28
#define IPV6_PLUS_ICMP_HDR 48
#define RING_SIZE 2
#define MAX_VIPS 12
#define MAX_REALS 5
#define CTL_MAP_SIZE 16
#define CH_RINGS_SIZE (MAX_VIPS * RING_SIZE)
#define F_IPV6 (1 << 0)
#define F_HASH_NO_SRC_PORT (1 << 0)
#define F_ICMP (1 << 0)
#define F_SYN_SET (1 << 1)

struct packet_description {
	union {
		__be32 src;
		__be32 srcv6[4];
	};
	union {
		__be32 dst;
		__be32 dstv6[4];
	};
	union {
		__u32 ports;
		__u16 port16[2];
	};
	__u8 proto;
	__u8 flags;
};

struct ctl_value {
	union {
		__u64 value;
		__u32 ifindex;
		__u8 mac[6];
	};
};

struct vip_meta {
	__u32 flags;
	__u32 vip_num;
};

struct real_definition {
	union {
		__be32 dst;
		__be32 dstv6[4];
	};
	__u8 flags;
};

struct vip_stats {
	__u64 bytes;
	__u64 pkts;
};

struct eth_hdr {
	unsigned char eth_dest[ETH_ALEN];
	unsigned char eth_source[ETH_ALEN];
	unsigned short eth_proto;
};

struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__uint(max_entries, MAX_VIPS);
	__type(key, struct vip);
	__type(value, struct vip_meta);
} vip_map SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, CH_RINGS_SIZE);
	__type(key, __u32);
	__type(value, __u32);
} ch_rings SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, MAX_REALS);
	__type(key, __u32);
	__type(value, struct real_definition);
} reals SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
	__uint(max_entries, MAX_VIPS);
	__type(key, __u32);
	__type(value, struct vip_stats);
} stats SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, CTL_MAP_SIZE);
	__type(key, __u32);
	__type(value, struct ctl_value);
} ctl_array SEC(".maps");

static __noinline __u32 get_packet_hash(struct packet_description *pckt, bool ipv6)
{
	if (ipv6)
		return jhash_2words(jhash(pckt->srcv6, 16, MAX_VIPS),
				    pckt->ports, CH_RINGS_SIZE);
	else
		return jhash_2words(pckt->src, pckt->ports, CH_RINGS_SIZE);
}

static __noinline bool get_packet_dst(struct real_definition **real,
				      struct packet_description *pckt,
				      struct vip_meta *vip_info,
				      bool is_ipv6)
{
	__u32 hash = get_packet_hash(pckt, is_ipv6);
	__u32 key = RING_SIZE * vip_info->vip_num + hash % RING_SIZE;
	__u32 *real_pos;

	if (hash != 0x358459b7 /* jhash of ipv4 packet */  &&
	    hash != 0x2f4bc6bb /* jhash of ipv6 packet */)
		return 0;

	real_pos = bpf_map_lookup_elem(&ch_rings, &key);
	if (!real_pos)
		return false;
	key = *real_pos;
	*real = bpf_map_lookup_elem(&reals, &key);
	if (!(*real))
		return false;
	return true;
}

static __noinline int parse_icmpv6(void *data, void *data_end, __u64 off,
				   struct packet_description *pckt)
{
	struct icmp6hdr *icmp_hdr;
	struct ipv6hdr *ip6h;

	icmp_hdr = data + off;
	if (icmp_hdr + 1 > data_end)
		return TC_ACT_SHOT;
	if (icmp_hdr->icmp6_type != ICMPV6_PKT_TOOBIG)
		return TC_ACT_OK;
	off += sizeof(struct icmp6hdr);
	ip6h = data + off;
	if (ip6h + 1 > data_end)
		return TC_ACT_SHOT;
	pckt->proto = ip6h->nexthdr;
	pckt->flags |= F_ICMP;
	memcpy(pckt->srcv6, ip6h->daddr.s6_addr32, 16);
	memcpy(pckt->dstv6, ip6h->saddr.s6_addr32, 16);
	return TC_ACT_UNSPEC;
}

static __noinline int parse_icmp(void *data, void *data_end, __u64 off,
				 struct packet_description *pckt)
{
	struct icmphdr *icmp_hdr;
	struct iphdr *iph;

	icmp_hdr = data + off;
	if (icmp_hdr + 1 > data_end)
		return TC_ACT_SHOT;
	if (icmp_hdr->type != ICMP_DEST_UNREACH ||
	    icmp_hdr->code != ICMP_FRAG_NEEDED)
		return TC_ACT_OK;
	off += sizeof(struct icmphdr);
	iph = data + off;
	if (iph + 1 > data_end)
		return TC_ACT_SHOT;
	if (iph->ihl != 5)
		return TC_ACT_SHOT;
	pckt->proto = iph->protocol;
	pckt->flags |= F_ICMP;
	pckt->src = iph->daddr;
	pckt->dst = iph->saddr;
	return TC_ACT_UNSPEC;
}

static __noinline bool parse_udp(void *data, __u64 off, void *data_end,
				 struct packet_description *pckt)
{
	struct udphdr *udp;
	udp = data + off;

	if (udp + 1 > data_end)
		return false;

	if (!(pckt->flags & F_ICMP)) {
		pckt->port16[0] = udp->source;
		pckt->port16[1] = udp->dest;
	} else {
		pckt->port16[0] = udp->dest;
		pckt->port16[1] = udp->source;
	}
	return true;
}

static __noinline bool parse_tcp(void *data, __u64 off, void *data_end,
				 struct packet_description *pckt)
{
	struct tcphdr *tcp;

	tcp = data + off;
	if (tcp + 1 > data_end)
		return false;

	if (tcp->syn)
		pckt->flags |= F_SYN_SET;

	if (!(pckt->flags & F_ICMP)) {
		pckt->port16[0] = tcp->source;
		pckt->port16[1] = tcp->dest;
	} else {
		pckt->port16[0] = tcp->dest;
		pckt->port16[1] = tcp->source;
	}
	return true;
}

static __noinline int process_packet(void *data, __u64 off, void *data_end,
				     bool is_ipv6, struct __sk_buff *skb)
{
	void *pkt_start = (void *)(long)skb->data;
	struct packet_description pckt = {};
	struct eth_hdr *eth = pkt_start;
	struct bpf_tunnel_key tkey = {};
	struct vip_stats *data_stats;
	struct real_definition *dst;
	struct vip_meta *vip_info;
	struct ctl_value *cval;
	__u32 v4_intf_pos = 1;
	__u32 v6_intf_pos = 2;
	struct ipv6hdr *ip6h;
	struct vip vip = {};
	struct iphdr *iph;
	int tun_flag = 0;
	__u16 pkt_bytes;
	__u64 iph_len;
	__u32 ifindex;
	__u8 protocol;
	__u32 vip_num;
	int action;

	tkey.tunnel_ttl = 64;
	if (is_ipv6) {
		ip6h = data + off;
		if (ip6h + 1 > data_end)
			return TC_ACT_SHOT;

		iph_len = sizeof(struct ipv6hdr);
		protocol = ip6h->nexthdr;
		pckt.proto = protocol;
		pkt_bytes = bpf_ntohs(ip6h->payload_len);
		off += iph_len;
		if (protocol == IPPROTO_FRAGMENT) {
			return TC_ACT_SHOT;
		} else if (protocol == IPPROTO_ICMPV6) {
			action = parse_icmpv6(data, data_end, off, &pckt);
			if (action >= 0)
				return action;
			off += IPV6_PLUS_ICMP_HDR;
		} else {
			memcpy(pckt.srcv6, ip6h->saddr.s6_addr32, 16);
			memcpy(pckt.dstv6, ip6h->daddr.s6_addr32, 16);
		}
	} else {
		iph = data + off;
		if (iph + 1 > data_end)
			return TC_ACT_SHOT;
		if (iph->ihl != 5)
			return TC_ACT_SHOT;

		protocol = iph->protocol;
		pckt.proto = protocol;
		pkt_bytes = bpf_ntohs(iph->tot_len);
		off += IPV4_HDR_LEN_NO_OPT;

		if (iph->frag_off & PCKT_FRAGMENTED)
			return TC_ACT_SHOT;
		if (protocol == IPPROTO_ICMP) {
			action = parse_icmp(data, data_end, off, &pckt);
			if (action >= 0)
				return action;
			off += IPV4_PLUS_ICMP_HDR;
		} else {
			pckt.src = iph->saddr;
			pckt.dst = iph->daddr;
		}
	}
	protocol = pckt.proto;

	if (protocol == IPPROTO_TCP) {
		if (!parse_tcp(data, off, data_end, &pckt))
			return TC_ACT_SHOT;
	} else if (protocol == IPPROTO_UDP) {
		if (!parse_udp(data, off, data_end, &pckt))
			return TC_ACT_SHOT;
	} else {
		return TC_ACT_SHOT;
	}

	if (is_ipv6)
		memcpy(vip.daddr.v6, pckt.dstv6, 16);
	else
		vip.daddr.v4 = pckt.dst;

	vip.dport = pckt.port16[1];
	vip.protocol = pckt.proto;
	vip_info = bpf_map_lookup_elem(&vip_map, &vip);
	if (!vip_info) {
		vip.dport = 0;
		vip_info = bpf_map_lookup_elem(&vip_map, &vip);
		if (!vip_info)
			return TC_ACT_SHOT;
		pckt.port16[1] = 0;
	}

	if (vip_info->flags & F_HASH_NO_SRC_PORT)
		pckt.port16[0] = 0;

	if (!get_packet_dst(&dst, &pckt, vip_info, is_ipv6))
		return TC_ACT_SHOT;

	if (dst->flags & F_IPV6) {
		cval = bpf_map_lookup_elem(&ctl_array, &v6_intf_pos);
		if (!cval)
			return TC_ACT_SHOT;
		ifindex = cval->ifindex;
		memcpy(tkey.remote_ipv6, dst->dstv6, 16);
		tun_flag = BPF_F_TUNINFO_IPV6;
	} else {
		cval = bpf_map_lookup_elem(&ctl_array, &v4_intf_pos);
		if (!cval)
			return TC_ACT_SHOT;
		ifindex = cval->ifindex;
		tkey.remote_ipv4 = dst->dst;
	}
	vip_num = vip_info->vip_num;
	data_stats = bpf_map_lookup_elem(&stats, &vip_num);
	if (!data_stats)
		return TC_ACT_SHOT;
	data_stats->pkts++;
	data_stats->bytes += pkt_bytes;
	bpf_skb_set_tunnel_key(skb, &tkey, sizeof(tkey), tun_flag);
	*(u32 *)eth->eth_dest = tkey.remote_ipv4;
	return bpf_redirect(ifindex, 0);
}

SEC("l4lb-demo")
int balancer_ingress(struct __sk_buff *ctx)
{
	void *data_end = (void *)(long)ctx->data_end;
	void *data = (void *)(long)ctx->data;
	struct eth_hdr *eth = data;
	__u32 eth_proto;
	__u32 nh_off;

	nh_off = sizeof(struct eth_hdr);
	if (data + nh_off > data_end)
		return TC_ACT_SHOT;
	eth_proto = eth->eth_proto;
	if (eth_proto == bpf_htons(ETH_P_IP))
		return process_packet(data, nh_off, data_end, false, ctx);
	else if (eth_proto == bpf_htons(ETH_P_IPV6))
		return process_packet(data, nh_off, data_end, true, ctx);
	else
		return TC_ACT_SHOT;
}
char _license[] SEC("license") = "GPL";
