/*
 **************************************************************************
 * Copyright (c) 2019-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_ovpnmgr_route.c
 */
#include <linux/etherdevice.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/if_tun.h>
#include <linux/ip.h>
#include <net/ip.h>
#include <net/udp.h>
#include <net/ip6_checksum.h>
#include <linux/ipv6.h>
#include <linux/crypto.h>
#include <crypto/algapi.h>
#include <crypto/aead.h>
#include <crypto/skcipher.h>
#include <crypto/aes.h>
#include <crypto/authenc.h>
#include <crypto/des.h>
#include <crypto/sha.h>
#include <crypto/hash.h>

#include <nss_api_if.h>
#include <nss_cryptoapi.h>
#include <nss_qvpn.h>
#include <nss_ovpnmgr.h>
#include "nss_ovpnmgr_crypto.h"
#include "nss_ovpnmgr_tun.h"
#include "nss_ovpnmgr_app.h"
#include "nss_ovpnmgr_debugfs.h"
#include "nss_ovpnmgr_priv.h"
#include "nss_ovpnmgr_route.h"

/*
 * nss_ovpnmgr_route_find()
 *	Return route for the given tunnel and address
 */
struct nss_ovpnmgr_route *nss_ovpnmgr_route_find(struct list_head *rt_list, struct nss_ovpnmgr_route_tuple *rt)
{
	struct nss_ovpnmgr_route *route;

	list_for_each_entry(route, rt_list, list) {
		if (route->rt.ip_version != rt->ip_version) {
			continue;
		}

		if (!memcmp(route->rt.ip_addr, rt->ip_addr, sizeof(rt->ip_addr))) {
			return route;
		}
	}

	return NULL;
}

/*
 * nss_ovpnmgr_route_set_active()
 *	Update OVPN tunnel route.
 */
int nss_ovpnmgr_route_set_active(struct list_head *rt_list, struct nss_ovpnmgr_route_tuple *rt)
{
	struct nss_ovpnmgr_route *route;

	/*
	 * This API should be called under lock.
	 */
	lockdep_assert_held(&ovpnmgr_ctx.lock);

	/*
	 * Search for route entry with from_addr.
	 */
	route = nss_ovpnmgr_route_find(rt_list, rt);
	if (!route) {
		nss_ovpnmgr_warn("%px: Route %x:%x:%x:%x not found\n", rt_list, rt->ip_addr[0],
				rt->ip_addr[1], rt->ip_addr[2], rt->ip_addr[3]);
		return -EINVAL;
	}

	route->in_use++;
	return 0;
}

/*
 * nss_ovpnmgr_route_is_active()
 *	Get route state.
 */
bool nss_ovpnmgr_route_is_active(uint32_t tunnel_id, struct nss_ovpnmgr_route_tuple *rt)
{
	struct nss_ovpnmgr_route *route;
	struct net_device *tun_dev;
	struct nss_ovpnmgr_tun *tun;

	tun_dev = dev_get_by_index(&init_net, tunnel_id);
	if (!tun_dev) {
		nss_ovpnmgr_warn("Couldn't find tunnel: tunnel_id = %u\n", tunnel_id);
		return false;
	}

	tun = netdev_priv(tun_dev);

	read_lock_bh(&ovpnmgr_ctx.lock);

	route = nss_ovpnmgr_route_find(&tun->route_list, rt);
	if (!route) {
		/*
		 * Route is not found.
		 */
		read_unlock_bh(&ovpnmgr_ctx.lock);
		dev_put(tun_dev);
		return false;
	}

	/*
	 * in_use is updated when packets hit flow entries in firmware are active
	 */
	if (route->in_use) {
		route->in_use = 0;
		read_unlock_bh(&ovpnmgr_ctx.lock);
		nss_ovpnmgr_info("%px: Route is active, don't delete\n", tun);
		dev_put(tun_dev);
		return true;
	}

	read_unlock_bh(&ovpnmgr_ctx.lock);

	dev_put(tun_dev);
	return false;
}
EXPORT_SYMBOL(nss_ovpnmgr_route_is_active);

/*
 * nss_ovpnmgr_route_del()
 *	Delete route from the tunnel.
 */
int nss_ovpnmgr_route_del(uint32_t tunnel_id, struct nss_ovpnmgr_route_tuple *rt)
{
	struct nss_ovpnmgr_route *route;
	struct net_device *tun_dev;
	struct nss_ovpnmgr_tun *tun;

	tun_dev = dev_get_by_index(&init_net, tunnel_id);
	if (!tun_dev) {
		nss_ovpnmgr_warn("Couldn't find tunnel: tunnel_id = %u\n\n", tunnel_id);
		return -ENODEV;
	}

	tun = netdev_priv(tun_dev);
	write_lock_bh(&ovpnmgr_ctx.lock);

	route = nss_ovpnmgr_route_find(&tun->route_list, rt);
	if (!route) {
		/*
		 * Route is not found.
		 */
		write_unlock_bh(&ovpnmgr_ctx.lock);
		dev_put(tun_dev);
		return -EINVAL;
	}

	nss_ovpnmgr_info("%px: Deleting route on tunnel id:%d\n", route, tunnel_id);

	list_del(&route->list);
	write_unlock_bh(&ovpnmgr_ctx.lock);

	kfree(route);
	dev_put(tun_dev);
	return 0;
}
EXPORT_SYMBOL(nss_ovpnmgr_route_del);

/*
 * nss_ovpnmgr_route_add()
 *	Add new route for the given tunnel
 */
int nss_ovpnmgr_route_add(uint32_t tunnel_id, struct nss_ovpnmgr_route_tuple *rt)
{
	struct nss_ovpnmgr_route *route;
	struct net_device *tun_dev;
	struct nss_ovpnmgr_tun *tun;

	tun_dev = dev_get_by_index(&init_net, tunnel_id);
	if (!tun_dev) {
		nss_ovpnmgr_warn("Couldn't find tunnel: tunnel_id = %u\n\n", tunnel_id);
		return -ENODEV;
	}

	tun = netdev_priv(tun_dev);

	/*
	 * Check if route is available.
	 */
	route = nss_ovpnmgr_route_find(&tun->route_list, rt);
	if (route) {
		nss_ovpnmgr_warn("%px: Route is available\n", tun);
		dev_put(tun_dev);
		return -EEXIST;
	}

	route = kzalloc(sizeof(*route), GFP_KERNEL);
	if (!route) {
		nss_ovpnmgr_warn("%px: Couldn't allocate memory for new route\n", tun);
		dev_put(tun_dev);
		return -ENOMEM;
	}

	memcpy(&route->rt, rt, sizeof(*rt));
	nss_ovpnmgr_info("%px: version = %d, IP = %x:%x:%x:%x\n", tun,
			route->rt.ip_version, route->rt.ip_addr[0],
			route->rt.ip_addr[1], route->rt.ip_addr[2],
			route->rt.ip_addr[3]);

	write_lock_bh(&ovpnmgr_ctx.lock);
	list_add(&route->list, &tun->route_list);
	write_unlock_bh(&ovpnmgr_ctx.lock);

	dev_put(tun_dev);
	return 0;
}
EXPORT_SYMBOL(nss_ovpnmgr_route_add);
