/* Copyright (C) 2017 Cavium, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 */
#define KBUILD_MODNAME "foo"
#include <uapi/linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include "bpf_helpers.h"
#include <linux/slab.h>
#include <net/ip_fib.h>

struct trie_value {
	__u8 prefix[4];
	__be64 value;
	int ifindex;
	int metric;
	__be32 gw;
};

/* Key for lpm_trie*/
union key_4 {
	u32 b32[2];
	u8 b8[8];
};

struct arp_entry {
	__be64 mac;
	__be32 dst;
};

struct direct_map {
	struct arp_entry arp;
	int ifindex;
	__be64 mac;
};

/* Map for trie implementation*/
struct {
	__uint(type, BPF_MAP_TYPE_LPM_TRIE);
	__uint(key_size, 8);
	__uint(value_size, sizeof(struct trie_value));
	__uint(max_entries, 50);
	__uint(map_flags, BPF_F_NO_PREALLOC);
} lpm_map SEC(".maps");

/* Map for counter*/
struct {
	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
	__type(key, u32);
	__type(value, u64);
	__uint(max_entries, 256);
} rxcnt SEC(".maps");

/* Map for ARP table*/
struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__type(key, __be32);
	__type(value, __be64);
	__uint(max_entries, 50);
} arp_table SEC(".maps");

/* Map to keep the exact match entries in the route table*/
struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__type(key, __be32);
	__type(value, struct direct_map);
	__uint(max_entries, 50);
} exact_match SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_DEVMAP);
	__uint(key_size, sizeof(int));
	__uint(value_size, sizeof(int));
	__uint(max_entries, 100);
} tx_port SEC(".maps");

/* Function to set source and destination mac of the packet */
static inline void set_src_dst_mac(void *data, void *src, void *dst)
{
	unsigned short *source = src;
	unsigned short *dest  = dst;
	unsigned short *p = data;

	__builtin_memcpy(p, dest, 6);
	__builtin_memcpy(p + 3, source, 6);
}

/* Parse IPV4 packet to get SRC, DST IP and protocol */
static inline int parse_ipv4(void *data, u64 nh_off, void *data_end,
			     __be32 *src, __be32 *dest)
{
	struct iphdr *iph = data + nh_off;

	if (iph + 1 > data_end)
		return 0;
	*src = iph->saddr;
	*dest = iph->daddr;
	return iph->protocol;
}

SEC("xdp_router_ipv4")
int xdp_router_ipv4_prog(struct xdp_md *ctx)
{
	void *data_end = (void *)(long)ctx->data_end;
	__be64 *dest_mac = NULL, *src_mac = NULL;
	void *data = (void *)(long)ctx->data;
	struct trie_value *prefix_value;
	int rc = XDP_DROP, forward_to;
	struct ethhdr *eth = data;
	union key_4 key4;
	long *value;
	u16 h_proto;
	u32 ipproto;
	u64 nh_off;

	nh_off = sizeof(*eth);
	if (data + nh_off > data_end)
		return rc;

	h_proto = eth->h_proto;

	if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
		struct vlan_hdr *vhdr;

		vhdr = data + nh_off;
		nh_off += sizeof(struct vlan_hdr);
		if (data + nh_off > data_end)
			return rc;
		h_proto = vhdr->h_vlan_encapsulated_proto;
	}
	if (h_proto == htons(ETH_P_ARP)) {
		return XDP_PASS;
	} else if (h_proto == htons(ETH_P_IP)) {
		struct direct_map *direct_entry;
		__be32 src_ip = 0, dest_ip = 0;

		ipproto = parse_ipv4(data, nh_off, data_end, &src_ip, &dest_ip);
		direct_entry = bpf_map_lookup_elem(&exact_match, &dest_ip);
		/* Check for exact match, this would give a faster lookup*/
		if (direct_entry && direct_entry->mac && direct_entry->arp.mac) {
			src_mac = &direct_entry->mac;
			dest_mac = &direct_entry->arp.mac;
			forward_to = direct_entry->ifindex;
		} else {
			/* Look up in the trie for lpm*/
			key4.b32[0] = 32;
			key4.b8[4] = dest_ip & 0xff;
			key4.b8[5] = (dest_ip >> 8) & 0xff;
			key4.b8[6] = (dest_ip >> 16) & 0xff;
			key4.b8[7] = (dest_ip >> 24) & 0xff;
			prefix_value = bpf_map_lookup_elem(&lpm_map, &key4);
			if (!prefix_value)
				return XDP_DROP;
			src_mac = &prefix_value->value;
			if (!src_mac)
				return XDP_DROP;
			dest_mac = bpf_map_lookup_elem(&arp_table, &dest_ip);
			if (!dest_mac) {
				if (!prefix_value->gw)
					return XDP_DROP;
				dest_ip = prefix_value->gw;
				dest_mac = bpf_map_lookup_elem(&arp_table, &dest_ip);
			}
			forward_to = prefix_value->ifindex;
		}
	} else {
		ipproto = 0;
	}
	if (src_mac && dest_mac) {
		set_src_dst_mac(data, src_mac, dest_mac);
		value = bpf_map_lookup_elem(&rxcnt, &ipproto);
		if (value)
			*value += 1;
		return  bpf_redirect_map(&tx_port, forward_to, 0);
	}
	return rc;
}

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