/*
 **************************************************************************
 * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **************************************************************************
 */

/*
 * nss_connnmgr_gre_v4.c
 *
 *  This file implements client for GRE implementation.
 */

#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <net/ip.h>
#include <net/route.h>
#include <net/ip_tunnels.h>
#include <net/ip6_tunnel.h>
#include <net/arp.h>
#include <net/gre.h>

#include <nss_api_if.h>
#include "nss_connmgr_gre_public.h"
#include "nss_connmgr_gre.h"

/*
 * nss_connmgr_gre_v4_get_tx_dev()
 *	Find tx interface for IP address. Holds ref to next_dev.
 */
static struct net_device *nss_connmgr_gre_v4_get_tx_dev(uint32_t dest_ip)
{
	struct rtable *rt;
	struct net_device *dev;
	uint32_t ip_addr __attribute__ ((unused)) = ntohl(dest_ip);

	rt = ip_route_output(&init_net, htonl(dest_ip), 0, 0, 0);
	if (IS_ERR(rt)) {
		nss_connmgr_gre_warning("Unable to lookup route for %pI4\n", &ip_addr);
		return NULL;
	}

	dev = rt->dst.dev;
	if (!dev) {
		ip_rt_put(rt);
		nss_connmgr_gre_warning("Unable to find route dev for %pI4\n", &ip_addr);
		return NULL;
	}

	dev_hold(dev);
	ip_rt_put(rt);
	return dev;
}

/*
 * nss_connmgr_gre_v4_get_mac_address()
 *	Find source and destination MAC for source and destination IP address.
 */
static int nss_connmgr_gre_v4_get_mac_address(uint32_t src_ip, uint32_t dest_ip,
					     uint8_t *src_mac, uint8_t *dest_mac)
{
	struct neighbour *neigh;
	struct rtable *rt;
	__be32 raddr = htonl(dest_ip);
	__be32 laddr = htonl(src_ip);

	/*
	 * find local MAC address
	 */
	struct net_device *local_dev = ip_dev_find(&init_net, laddr);
	if (!local_dev) {
		nss_connmgr_gre_warning("Unable to find local dev for %pI4", &laddr);
		return GRE_ERR_NO_LOCAL_NETDEV;
	}
	ether_addr_copy(src_mac, local_dev->dev_addr);
	dev_put(local_dev);
	nss_connmgr_gre_info("Src MAC address for %pI4 is %pM\n", &laddr, src_mac);

	rt = ip_route_output(&init_net, raddr, 0, 0, 0);
	if (IS_ERR(rt)) {
		nss_connmgr_gre_warning("route look up failed for %pI4\n", &raddr);
		return GRE_ERR_RADDR_ROUTE_LOOKUP;
	}

	neigh = dst_neigh_lookup(&rt->dst, (const void *)&raddr);
	if (!neigh) {
		neigh = neigh_lookup(&arp_tbl, (const void *)&raddr,  rt->dst.dev);
	}

	if (neigh) {
		if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
			nss_connmgr_gre_info("neigh lookup failed for %pI4, state=%x, neigh->ha=%pM\n", &raddr, neigh->nud_state, neigh->ha);
			neigh_release(neigh);
			neigh = NULL;
		}
	}

	/*
	 * Send arp request
	 */
	if (!neigh) {
		neigh = neigh_create(&arp_tbl, &raddr, rt->dst.dev);
		if (IS_ERR_OR_NULL(neigh)) {
			nss_connmgr_gre_warning("Unable to create ARP request neigh for %pI4\n", &raddr);
			ip_rt_put(rt);
			return GRE_ERR_NEIGH_CREATE;
		}
		nss_connmgr_gre_info("Send ARP request neigh for %pI4\n", &raddr);
		neigh_event_send(neigh, NULL);

		msleep(2000);
	}

	if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
		ip_rt_put(rt);
		nss_connmgr_gre_warning("invalid neigh state (%x) or invalid MAC(%pM) for %pI4\n", neigh->nud_state, neigh->ha,  &raddr);
		neigh_release(neigh);
		return GRE_ERR_NEIGH_CREATE;
	}

	if (neigh->dev->type == ARPHRD_LOOPBACK) {
		ip_rt_put(rt);
		neigh_release(neigh);
		nss_connmgr_gre_warning("Err in destination MAC address, neighbour dev is loop back for %pI4\n", &raddr);
		return GRE_ERR_NEIGH_DEV_LOOPBACK;

	}

	if (neigh->dev->flags & IFF_NOARP) {
		ip_rt_put(rt);
		neigh_release(neigh);
		nss_connmgr_gre_warning("Err in destination MAC address, neighbour dev is of type NO_ARP for %pI4\n", &raddr);
		return GRE_ERR_NEIGH_DEV_NOARP;
	}

	ether_addr_copy(dest_mac, neigh->ha);
	ip_rt_put(rt);
	neigh_release(neigh);
	nss_connmgr_gre_info("Destination MAC address for %pI4 is %pM\n", &raddr, dest_mac);
	return GRE_SUCCESS;
}

/*
 * nss_connmgr_gre_v4_set_config()
 *	Set User configuration to netdevice
 */
int nss_connmgr_gre_v4_set_config(struct net_device *dev, struct nss_connmgr_gre_cfg *cfg)
{
	nss_connmgr_gre_priv_t *priv = netdev_priv(dev);
	struct ip_tunnel *t = (struct ip_tunnel *)priv;
	struct iphdr *iphdr;

	/*
	 * MAC address validate
	 */
	if (cfg->use_mac_hdr) {
		if (!is_valid_ether_addr((const u8 *)cfg->src_mac) ||
		    !is_valid_ether_addr((const u8 *)cfg->dest_mac)) {
			nss_connmgr_gre_warning("User should provide valid MAC address if flag add_mac hdr is set\n");
			return GRE_ERR_INVALID_MAC;
		}
	}

	/*
	 * IP address validate
	 */
	if ((cfg->src_ip == 0) || (cfg->dest_ip == 0)) {
		nss_connmgr_gre_warning("Source ip/Destination IP is invalid");
		return GRE_ERR_INVALID_IP;
	}

	memset(t, 0, sizeof(struct ip_tunnel));

	priv->pad_len =  (cfg->add_padding) ? GRE_HDR_PAD_LEN : 0;
	priv->gre_hlen = nss_connmgr_gre_get_hlen(cfg);

	iphdr = (struct iphdr *)&(t->parms.iph);
	iphdr->protocol = IPPROTO_GRE;

	memcpy(&iphdr->saddr, (uint8_t *)cfg->src_ip, 4);
	memcpy(&iphdr->daddr, (uint8_t *)cfg->dest_ip, 4);

	iphdr->saddr = htonl(iphdr->saddr);
	iphdr->daddr = htonl(iphdr->daddr);

	iphdr->tos = cfg->tos << 2;
	if (cfg->tos_inherit) {
		iphdr->tos |= 0x1;
	}

	iphdr->ttl = cfg->ttl;
	if (cfg->ttl_inherit) {
		iphdr->ttl = 0;
	}

	if (cfg->set_df) {
		iphdr->frag_off = htons(IP_DF);
	}

	if (cfg->ikey_valid) {
		t->parms.i_key = cfg->ikey;
	}

	if (cfg->okey_valid) {
		t->parms.o_key = cfg->okey;
	}

	nss_connmgr_gre_set_gre_flags(cfg, &t->parms.o_flags, &t->parms.i_flags);

	strlcpy(t->parms.name, dev->name, IFNAMSIZ);
	t->dev = dev;
	return GRE_SUCCESS;
}

/*
 * nss_connmgr_gre_tap_v4_outer_exception()
 * 	Handle IPv4 exception for GRETAP outer device
 */
void nss_connmgr_gre_tap_v4_outer_exception(struct net_device *dev, struct sk_buff *skb)
{
	struct ethhdr *eth_hdr = (struct ethhdr *)skb->data;

	/*
	 * GRE encapsulated packet exceptioned, remove the encapsulation
	 * and transmit on GRE interface.
	 */
	if (unlikely(!pskb_may_pull(skb, (sizeof(struct ethhdr) + sizeof(struct iphdr)
				+ sizeof(struct gre_base_hdr))))) {
		nss_connmgr_gre_warning("%px: pskb_may_pull failed for skb:%px\n", dev, skb);
		dev_kfree_skb_any(skb);
		return;
	}

	/*
	 * TODO: Support parsing GRE options
	 */
	skb_pull(skb, (sizeof(struct ethhdr) + sizeof(struct iphdr)
				+ sizeof(struct gre_base_hdr)));

	if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr)))) {
		nss_connmgr_gre_warning("%px: pskb_may_pull failed for skb:%px\n", dev, skb);
		dev_kfree_skb_any(skb);
		return;
	}
	skb->dev = dev;
	if (likely(ntohs(eth_hdr->h_proto) >= ETH_P_802_3_MIN)) {
		skb->protocol = eth_hdr->h_proto;
	} else {
		skb->protocol = htons(ETH_P_802_2);
	}
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	skb_reset_transport_header(skb);
	skb_reset_mac_len(skb);
	dev_queue_xmit(skb);
}

/*
 * nss_connmgr_gre_tun_v4_outer_exception()
 * 	Handle IPv4 exception for GRETUN outer device
 */
void nss_connmgr_gre_tun_v4_outer_exception(struct net_device *dev, struct sk_buff *skb)
{
	struct iphdr *iph;

	/*
	 * GRE encapsulated packet exceptioned, remove the encapsulation
	 * and transmit on GRE interface.
	 */
	if (unlikely(!pskb_may_pull(skb, sizeof(struct iphdr) + sizeof(struct gre_base_hdr)))) {
		nss_connmgr_gre_warning("%px: pskb_may_pull failed for skb:%px\n", dev, skb);
		dev_kfree_skb_any(skb);
		return;
	}

	/*
	 * TODO: Support parsing GRE options
	 */
	skb_pull(skb, sizeof(struct iphdr) + sizeof(struct gre_base_hdr));
	iph = (struct iphdr *)skb->data;
	skb->dev = dev;

	switch (iph->version) {
	case 4:
		skb->protocol = htons(ETH_P_IP);
		break;
	case 6:
		skb->protocol = htons(ETH_P_IPV6);
		break;
	default:
		nss_connmgr_gre_info("%px: wrong IP version in GRE encapped packet. skb: %px\n", dev, skb);
		dev_kfree_skb_any(skb);
		return;
	}

	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	skb_reset_transport_header(skb);
	skb_reset_mac_len(skb);
	dev_queue_xmit(skb);
}

/*
 * nss_connmgr_gre_v4_get_config()
 *	Fill in config message to send to NSS.
 */
int nss_connmgr_gre_v4_get_config(struct net_device *dev, struct nss_gre_msg *req,
				  struct net_device **next_dev, bool hold)
{
	uint32_t src_ip, dest_ip;
	struct ip_tunnel *t = netdev_priv(dev);
	struct iphdr *iphdr = (struct iphdr *)&(t->parms.iph);
	struct net_device *out_dev;
	struct nss_gre_config_msg *cmsg = &req->msg.cmsg;
	int ret;

	src_ip = ntohl(iphdr->saddr);
	dest_ip = ntohl(iphdr->daddr);
	memcpy(cmsg->src_ip, &src_ip, 4);
	memcpy(cmsg->dest_ip, &dest_ip, 4);

	cmsg->flags |= nss_connmgr_gre_get_nss_config_flags(t->parms.o_flags,
								     t->parms.i_flags,
								     iphdr->tos, iphdr->ttl,
								     iphdr->frag_off);

	cmsg->ikey = t->parms.i_key;
	cmsg->okey = t->parms.o_key;
	cmsg->ttl = iphdr->ttl;
	cmsg->tos = iphdr->tos >> 2;

	/*
	 * fill in MAC addresses
	 */
	ret = nss_connmgr_gre_v4_get_mac_address(src_ip, dest_ip,
						 (uint8_t *)cmsg->src_mac,
						 (uint8_t *)cmsg->dest_mac);
	if (!ret) {
		cmsg->flags |= NSS_GRE_CONFIG_SET_MAC;
	}

	/*
	 * fill in NSS interface number
	 */
	out_dev = nss_connmgr_gre_v4_get_tx_dev(dest_ip);
	if (out_dev) {
		cmsg->next_node_if_num = nss_cmn_get_interface_number_by_dev(out_dev);
		cmsg->flags |= NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE;
		*next_dev = out_dev;
		if (!hold) {
			dev_put(out_dev);
		}
	}

	return GRE_SUCCESS;
}
