/*
 * Copyright (C) 2017 - Cambridge Greys Limited
 * Copyright (C) 2011 - 2014 Cisco Systems Inc
 * Licensed under the GPL.
 */

#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/virtio_net.h>
#include <linux/virtio_net.h>
#include <linux/virtio_byteorder.h>
#include <linux/netdev_features.h>
#include "vector_user.h"
#include "vector_kern.h"

#define GOOD_LINEAR 512
#define GSO_ERROR "Incoming GSO frames and GRO disabled on the interface"

struct gre_minimal_header {
	uint16_t header;
	uint16_t arptype;
};


struct uml_gre_data {
	uint32_t rx_key;
	uint32_t tx_key;
	uint32_t sequence;

	bool ipv6;
	bool has_sequence;
	bool pin_sequence;
	bool checksum;
	bool key;
	struct gre_minimal_header expected_header;

	uint32_t checksum_offset;
	uint32_t key_offset;
	uint32_t sequence_offset;

};

struct uml_l2tpv3_data {
	uint64_t rx_cookie;
	uint64_t tx_cookie;
	uint64_t rx_session;
	uint64_t tx_session;
	uint32_t counter;

	bool udp;
	bool ipv6;
	bool has_counter;
	bool pin_counter;
	bool cookie;
	bool cookie_is_64;

	uint32_t cookie_offset;
	uint32_t session_offset;
	uint32_t counter_offset;
};

static int l2tpv3_form_header(uint8_t *header,
	struct sk_buff *skb, struct vector_private *vp)
{
	struct uml_l2tpv3_data *td = vp->transport_data;
	uint32_t *counter;

	if (td->udp)
		*(uint32_t *) header = cpu_to_be32(L2TPV3_DATA_PACKET);
	(*(uint32_t *) (header + td->session_offset)) = td->tx_session;

	if (td->cookie) {
		if (td->cookie_is_64)
			(*(uint64_t *)(header + td->cookie_offset)) =
				td->tx_cookie;
		else
			(*(uint32_t *)(header + td->cookie_offset)) =
				td->tx_cookie;
	}
	if (td->has_counter) {
		counter = (uint32_t *)(header + td->counter_offset);
		if (td->pin_counter) {
			*counter = 0;
		} else {
			td->counter++;
			*counter = cpu_to_be32(td->counter);
		}
	}
	return 0;
}

static int gre_form_header(uint8_t *header,
		struct sk_buff *skb, struct vector_private *vp)
{
	struct uml_gre_data *td = vp->transport_data;
	uint32_t *sequence;
	*((uint32_t *) header) = *((uint32_t *) &td->expected_header);
	if (td->key)
		(*(uint32_t *) (header + td->key_offset)) = td->tx_key;
	if (td->has_sequence) {
		sequence = (uint32_t *)(header + td->sequence_offset);
		if (td->pin_sequence)
			*sequence = 0;
		else
			*sequence = cpu_to_be32(++td->sequence);
	}
	return 0;
}

static int raw_form_header(uint8_t *header,
		struct sk_buff *skb, struct vector_private *vp)
{
	struct virtio_net_hdr *vheader = (struct virtio_net_hdr *) header;

	virtio_net_hdr_from_skb(
		skb,
		vheader,
		virtio_legacy_is_little_endian(),
		false
	);

	return 0;
}

static int l2tpv3_verify_header(
	uint8_t *header, struct sk_buff *skb, struct vector_private *vp)
{
	struct uml_l2tpv3_data *td = vp->transport_data;
	uint32_t *session;
	uint64_t cookie;

	if ((!td->udp) && (!td->ipv6))
		header += sizeof(struct iphdr) /* fix for ipv4 raw */;

	/* we do not do a strict check for "data" packets as per
	 * the RFC spec because the pure IP spec does not have
	 * that anyway.
	 */

	if (td->cookie) {
		if (td->cookie_is_64)
			cookie = *(uint64_t *)(header + td->cookie_offset);
		else
			cookie = *(uint32_t *)(header + td->cookie_offset);
		if (cookie != td->rx_cookie) {
			if (net_ratelimit())
				netdev_err(vp->dev, "uml_l2tpv3: unknown cookie id");
			return -1;
		}
	}
	session = (uint32_t *) (header + td->session_offset);
	if (*session != td->rx_session) {
		if (net_ratelimit())
			netdev_err(vp->dev, "uml_l2tpv3: session mismatch");
		return -1;
	}
	return 0;
}

static int gre_verify_header(
	uint8_t *header, struct sk_buff *skb, struct vector_private *vp)
{

	uint32_t key;
	struct uml_gre_data *td = vp->transport_data;

	if (!td->ipv6)
		header += sizeof(struct iphdr) /* fix for ipv4 raw */;

	if (*((uint32_t *) header) != *((uint32_t *) &td->expected_header)) {
		if (net_ratelimit())
			netdev_err(vp->dev, "header type disagreement, expecting %0x, got %0x",
				*((uint32_t *) &td->expected_header),
				*((uint32_t *) header)
			);
		return -1;
	}

	if (td->key) {
		key = (*(uint32_t *)(header + td->key_offset));
		if (key != td->rx_key) {
			if (net_ratelimit())
				netdev_err(vp->dev, "unknown key id %0x, expecting %0x",
						key, td->rx_key);
			return -1;
		}
	}
	return 0;
}

static int raw_verify_header(
	uint8_t *header, struct sk_buff *skb, struct vector_private *vp)
{
	struct virtio_net_hdr *vheader = (struct virtio_net_hdr *) header;

	if ((vheader->gso_type != VIRTIO_NET_HDR_GSO_NONE) &&
		(vp->req_size != 65536)) {
		if (net_ratelimit())
			netdev_err(
				vp->dev,
				GSO_ERROR
		);
	}
	if ((vheader->flags & VIRTIO_NET_HDR_F_DATA_VALID) > 0)
		return 1;

	virtio_net_hdr_to_skb(skb, vheader, virtio_legacy_is_little_endian());
	return 0;
}

static bool get_uint_param(
	struct arglist *def, char *param, unsigned int *result)
{
	char *arg = uml_vector_fetch_arg(def, param);

	if (arg != NULL) {
		if (kstrtoint(arg, 0, result) == 0)
			return true;
	}
	return false;
}

static bool get_ulong_param(
	struct arglist *def, char *param, unsigned long *result)
{
	char *arg = uml_vector_fetch_arg(def, param);

	if (arg != NULL) {
		if (kstrtoul(arg, 0, result) == 0)
			return true;
		return true;
	}
	return false;
}

static int build_gre_transport_data(struct vector_private *vp)
{
	struct uml_gre_data *td;
	int temp_int;
	int temp_rx;
	int temp_tx;

	vp->transport_data = kmalloc(sizeof(struct uml_gre_data), GFP_KERNEL);
	if (vp->transport_data == NULL)
		return -ENOMEM;
	td = vp->transport_data;
	td->sequence = 0;

	td->expected_header.arptype = GRE_IRB;
	td->expected_header.header = 0;

	vp->form_header = &gre_form_header;
	vp->verify_header = &gre_verify_header;
	vp->header_size = 4;
	td->key_offset = 4;
	td->sequence_offset = 4;
	td->checksum_offset = 4;

	td->ipv6 = false;
	if (get_uint_param(vp->parsed, "v6", &temp_int)) {
		if (temp_int > 0)
			td->ipv6 = true;
	}
	td->key = false;
	if (get_uint_param(vp->parsed, "rx_key", &temp_rx)) {
		if (get_uint_param(vp->parsed, "tx_key", &temp_tx)) {
			td->key = true;
			td->expected_header.header |= GRE_MODE_KEY;
			td->rx_key = cpu_to_be32(temp_rx);
			td->tx_key = cpu_to_be32(temp_tx);
			vp->header_size += 4;
			td->sequence_offset += 4;
		} else {
			return -EINVAL;
		}
	}

	td->sequence = false;
	if (get_uint_param(vp->parsed, "sequence", &temp_int)) {
		if (temp_int > 0) {
			vp->header_size += 4;
			td->has_sequence = true;
			td->expected_header.header |= GRE_MODE_SEQUENCE;
			if (get_uint_param(
				vp->parsed, "pin_sequence", &temp_int)) {
				if (temp_int > 0)
					td->pin_sequence = true;
			}
		}
	}
	vp->rx_header_size = vp->header_size;
	if (!td->ipv6)
		vp->rx_header_size += sizeof(struct iphdr);
	return 0;
}

static int build_l2tpv3_transport_data(struct vector_private *vp)
{

	struct uml_l2tpv3_data *td;
	int temp_int, temp_rxs, temp_txs;
	unsigned long temp_rx;
	unsigned long temp_tx;

	vp->transport_data = kmalloc(
		sizeof(struct uml_l2tpv3_data), GFP_KERNEL);

	if (vp->transport_data == NULL)
		return -ENOMEM;

	td = vp->transport_data;

	vp->form_header = &l2tpv3_form_header;
	vp->verify_header = &l2tpv3_verify_header;
	td->counter = 0;

	vp->header_size = 4;
	td->session_offset = 0;
	td->cookie_offset = 4;
	td->counter_offset = 4;


	td->ipv6 = false;
	if (get_uint_param(vp->parsed, "v6", &temp_int)) {
		if (temp_int > 0)
			td->ipv6 = true;
	}

	if (get_uint_param(vp->parsed, "rx_session", &temp_rxs)) {
		if (get_uint_param(vp->parsed, "tx_session", &temp_txs)) {
			td->tx_session = cpu_to_be32(temp_txs);
			td->rx_session = cpu_to_be32(temp_rxs);
		} else {
			return -EINVAL;
		}
	} else {
		return -EINVAL;
	}

	td->cookie_is_64  = false;
	if (get_uint_param(vp->parsed, "cookie64", &temp_int)) {
		if (temp_int > 0)
			td->cookie_is_64  = true;
	}
	td->cookie = false;
	if (get_ulong_param(vp->parsed, "rx_cookie", &temp_rx)) {
		if (get_ulong_param(vp->parsed, "tx_cookie", &temp_tx)) {
			td->cookie = true;
			if (td->cookie_is_64) {
				td->rx_cookie = cpu_to_be64(temp_rx);
				td->tx_cookie = cpu_to_be64(temp_tx);
				vp->header_size += 8;
				td->counter_offset += 8;
			} else {
				td->rx_cookie = cpu_to_be32(temp_rx);
				td->tx_cookie = cpu_to_be32(temp_tx);
				vp->header_size += 4;
				td->counter_offset += 4;
			}
		} else {
			return -EINVAL;
		}
	}

	td->has_counter = false;
	if (get_uint_param(vp->parsed, "counter", &temp_int)) {
		if (temp_int > 0) {
			td->has_counter = true;
			vp->header_size += 4;
			if (get_uint_param(
				vp->parsed, "pin_counter", &temp_int)) {
				if (temp_int > 0)
					td->pin_counter = true;
			}
		}
	}

	if (get_uint_param(vp->parsed, "udp", &temp_int)) {
		if (temp_int > 0) {
			td->udp = true;
			vp->header_size += 4;
			td->counter_offset += 4;
			td->session_offset += 4;
			td->cookie_offset += 4;
		}
	}

	vp->rx_header_size = vp->header_size;
	if ((!td->ipv6) && (!td->udp))
		vp->rx_header_size += sizeof(struct iphdr);

	return 0;
}

static int build_raw_transport_data(struct vector_private *vp)
{
	if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) {
		if (!uml_raw_enable_vnet_headers(vp->fds->tx_fd))
			return -1;
		vp->form_header = &raw_form_header;
		vp->verify_header = &raw_verify_header;
		vp->header_size = sizeof(struct virtio_net_hdr);
		vp->rx_header_size = sizeof(struct virtio_net_hdr);
		vp->dev->hw_features |= (NETIF_F_TSO | NETIF_F_GRO);
		vp->dev->features |=
			(NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
				NETIF_F_TSO | NETIF_F_GRO);
		netdev_info(
			vp->dev,
			"raw: using vnet headers for tso and tx/rx checksum"
		);
	}
	return 0;
}

static int build_tap_transport_data(struct vector_private *vp)
{
	if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) {
		vp->form_header = &raw_form_header;
		vp->verify_header = &raw_verify_header;
		vp->header_size = sizeof(struct virtio_net_hdr);
		vp->rx_header_size = sizeof(struct virtio_net_hdr);
		vp->dev->hw_features |=
			(NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO);
		vp->dev->features |=
			(NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
				NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO);
		netdev_info(
			vp->dev,
			"tap/raw: using vnet headers for tso and tx/rx checksum"
		);
	} else {
		return 0; /* do not try to enable tap too if raw failed */
	}
	if (uml_tap_enable_vnet_headers(vp->fds->tx_fd))
		return 0;
	return -1;
}

int build_transport_data(struct vector_private *vp)
{
	char *transport = uml_vector_fetch_arg(vp->parsed, "transport");

	if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0)
		return build_gre_transport_data(vp);
	if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0)
		return build_l2tpv3_transport_data(vp);
	if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
		return build_raw_transport_data(vp);
	if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
		return build_tap_transport_data(vp);
	return 0;
}

