/*
 **************************************************************************
 * Copyright (c) 2017-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_v6.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/route.h>
#include <net/ip6_route.h>
#include <net/ip6_tunnel.h>
#include <net/ip_tunnels.h>
#include <net/addrconf.h>
#include <net/gre.h>

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

/*
 * nss_connmgr_gre_v6_route_lookup()
 *	Find IPv6 route for the IP address
 */
static inline struct rt6_info *nss_connmgr_gre_v6_route_lookup(struct net *net, struct in6_addr *addr)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
        return rt6_lookup(net, addr, NULL, 0, 0);
#else
	return rt6_lookup(net, addr, NULL, 0, 0, 0);
#endif
}

/*
 * nss_connmgr_gre_v6_get_tx_dev()
 *	Find tx interface for the IP address.
 */
static struct net_device *nss_connmgr_gre_v6_get_tx_dev(uint8_t *dest_ip)
{
	struct rt6_info *rt;
	struct in6_addr ipv6_addr;
	struct net_device *dev;

	memcpy(ipv6_addr.s6_addr, dest_ip, 16);

	rt = nss_connmgr_gre_v6_route_lookup(&init_net, &ipv6_addr);
	if (!rt) {
		return NULL;
	}

	dev = rt->dst.dev;
	if (!dev) {
		ip6_rt_put(rt);
		return NULL;
	}

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

/*
 * nss_connmgr_gre_v6_get_mac_address()
 *	Find source and destination MAC address for source and destination IP
 *	address.
 */
static int nss_connmgr_gre_v6_get_mac_address(uint8_t *src_ip, uint8_t *dest_ip,
					     uint8_t *src_mac, uint8_t *dest_mac)
{
	struct neighbour *neigh;
	struct rt6_info *rt;
	struct in6_addr src_addr, dst_addr, mc_dst_addr;
	struct net_device *local_dev;

	memcpy(src_addr.s6_addr, src_ip, 16);
	memcpy(dst_addr.s6_addr, dest_ip, 16);

	/*
	 * Find src MAC address
	 */
	local_dev = (struct net_device *)ipv6_dev_find(&init_net, &src_addr, 1);
	if (!local_dev) {
		nss_connmgr_gre_warning("Unable to find local dev for %pI6", src_ip);
		return GRE_ERR_NO_LOCAL_NETDEV;
	}
	ether_addr_copy(src_mac, local_dev->dev_addr);
	dev_put(local_dev);

	/*
	 * Find dest MAC address
	 */

	rt = nss_connmgr_gre_v6_route_lookup(&init_net, &dst_addr);
	if (!rt) {
		nss_connmgr_gre_warning("Unable to find route lookup for %pI6", dest_ip);
		return GRE_ERR_NEIGH_LOOKUP;
	}

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
	neigh = rt->dst.ops->neigh_lookup(&rt->dst, &dst_addr);
#else
	neigh = rt->dst.ops->neigh_lookup(&rt->dst, NULL, &dst_addr);
#endif
	if (neigh) {
		if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
			nss_connmgr_gre_warning("neigh state is either invalid (%x) or mac address is null (%pM) for %pI6", neigh->nud_state, neigh->ha, dest_ip);
			neigh_release(neigh);
			neigh = NULL;
		}
	}

	if (!neigh) {

		/*
		 * Issue a Neighbour soliciation request
	 	*/
		nss_connmgr_gre_info("Issue Neighbour solicitation request\n");
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
		ndisc_send_ns(local_dev, &dst_addr, &mc_dst_addr, &src_addr);
#else
		ndisc_send_ns(local_dev, &dst_addr, &mc_dst_addr, &src_addr, 0);
#endif
		msleep(2000);

		/*
		 * Release hold on existing route entry, and find the route entry again
		 */
		ip6_rt_put(rt);

		rt = nss_connmgr_gre_v6_route_lookup(&init_net, &dst_addr);
		if (!rt) {
			nss_connmgr_gre_warning("Unable to find route lookup for %pI6\n", dest_ip);
			return GRE_ERR_NEIGH_LOOKUP;
		}

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
		neigh = rt->dst.ops->neigh_lookup(&rt->dst, &dst_addr);
#else
		neigh = rt->dst.ops->neigh_lookup(&rt->dst, NULL, &dst_addr);
#endif

		if (!neigh) {
			ip6_rt_put(rt);
			nss_connmgr_gre_warning("Err in MAC address, neighbour look up failed\n");
			return GRE_ERR_NEIGH_LOOKUP;
		}

		if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
			ip6_rt_put(rt);
			nss_connmgr_gre_warning("Err in MAC address, invalid neigh state (%x) or invalid mac(%pM)\n", neigh->nud_state, neigh->ha);
			neigh_release(neigh);
			return GRE_ERR_NEIGH_LOOKUP;
		}
	}

	ether_addr_copy(dest_mac, neigh->ha);

	ip6_rt_put(rt);
	neigh_release(neigh);
	return GRE_SUCCESS;
}

/*
 * nss_connmgr_gre_tap_v6_outer_exception()
 * 	Handle IPv6 exception for GRETAP outer device
 */
void nss_connmgr_gre_tap_v6_outer_exception(struct net_device *dev, struct sk_buff *skb)
{
	struct ethhdr *eth = (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 ipv6hdr)
				+ 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 ipv6hdr)
				+ 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->h_proto) >= ETH_P_802_3_MIN)) {
		skb->protocol = eth->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_v6_outer_exception()
 * 	Handle IPv6 exception for GRETUN outer device
 */
void nss_connmgr_gre_tun_v6_outer_exception(struct net_device *dev, struct sk_buff *skb)
{
	struct ipv6hdr *ip6h;

	/*
	 * GRE encapsulated packet exceptioned, remove the encapsulation
	 * and transmit on GRE interface.
	 */
	if (unlikely(!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 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 ipv6hdr) + sizeof(struct gre_base_hdr));

	ip6h = (struct ipv6hdr *)skb->data;
	skb->dev = dev;

	switch (ip6h->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_v6_set_config()
 *	Set user config to dev inerface.
 */
int nss_connmgr_gre_v6_set_config(struct net_device *dev, struct nss_connmgr_gre_cfg *cfg)
{
	nss_connmgr_gre_priv_t *priv = netdev_priv(dev);
	struct ip6_tnl *t = (struct ip6_tnl *)priv;

	/*
	 * IP address validate
	 */
	if (ipv6_addr_any(((const struct in6_addr *)&cfg->src_ip)) ||
	    ipv6_addr_any(((const struct in6_addr *)&cfg->dest_ip))) {
		nss_connmgr_gre_warning("Source ip/Destination IP is invalid");
		return  GRE_ERR_INVALID_IP;
	}

	/*
	 * 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;
		}
	}

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

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

	memcpy(t->parms.laddr.s6_addr, &cfg->src_ip, 16);
	memcpy(t->parms.raddr.s6_addr, &cfg->dest_ip, 16);

	t->parms.flowinfo = cfg->tos << 2;
	if (cfg->tos_inherit) {
		t->parms.flowinfo |= 0x1;
	}

	t->parms.hop_limit = cfg->ttl;
	if (cfg->ttl_inherit) {
		t->parms.hop_limit = 0;
	}

	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_v6_get_config()
 *	Fill info in config message to send to NSS.
 */
int nss_connmgr_gre_v6_get_config(struct net_device *dev, struct nss_gre_msg *req,
				  struct net_device **next_dev, bool hold)
{
	struct ip6_tnl *t = netdev_priv(dev);
	struct net_device *out_dev;
	struct nss_gre_config_msg *cmsg = &req->msg.cmsg;
	int ret;
	struct in6_addr *src_ip = &t->parms.laddr;
	struct in6_addr *dest_ip = &t->parms.raddr;

	/*
	 * Store IPv6 addresses in host endian in the message.
	 */
	cmsg->src_ip[0] = ntohl(src_ip->in6_u.u6_addr32[0]);
	cmsg->src_ip[1] = ntohl(src_ip->in6_u.u6_addr32[1]);
	cmsg->src_ip[2] = ntohl(src_ip->in6_u.u6_addr32[2]);
	cmsg->src_ip[3] = ntohl(src_ip->in6_u.u6_addr32[3]);

	cmsg->dest_ip[0] = ntohl(dest_ip->in6_u.u6_addr32[0]);
	cmsg->dest_ip[1] = ntohl(dest_ip->in6_u.u6_addr32[1]);
	cmsg->dest_ip[2] = ntohl(dest_ip->in6_u.u6_addr32[2]);
	cmsg->dest_ip[3] = ntohl(dest_ip->in6_u.u6_addr32[3]);

	/*
	 * IPv6 outer tos field is always inherited from inner IP header.
	 */
	cmsg->flags |= nss_connmgr_gre_get_nss_config_flags(t->parms.o_flags,
								     t->parms.i_flags,
								     t->parms.flowinfo,
								     t->parms.hop_limit, 0);

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

	/*
	 * fill in MAC addresses
	 */
	ret = nss_connmgr_gre_v6_get_mac_address(t->parms.laddr.s6_addr, t->parms.raddr.s6_addr,
						 (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_v6_get_tx_dev(t->parms.raddr.s6_addr);
	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;
}
