/*
 **************************************************************************
 * 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.
 **************************************************************************
 */

#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/rwlock_types.h>
#include <linux/hashtable.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/ip.h>
#include <net/ipv6.h>
#include <linux/if_arp.h>
#include <net/route.h>
#include <linux/if_pppox.h>
#include <net/ip.h>
#include <linux/if_bridge.h>
#include <net/bonding.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#endif
#include <nss_api_if.h>
#include <nss_dynamic_interface.h>
#include "nss_connmgr_pppoe.h"

#define HASH_BUCKET_SIZE 2  /* ( 2^ HASH_BUCKET_SIZE ) == 4 */

static DEFINE_HASHTABLE(pppoe_session_table, HASH_BUCKET_SIZE);

/*
 * nss_connmgr_pppoe_get_session()
 *	Retrieve pppoe session associated with this netdevice if any
 */
static int nss_connmgr_pppoe_get_session(struct net_device *dev,  struct pppoe_opt *addressing)
{
	struct ppp_channel *channel[1] = {NULL};
	int px_proto;
	int ppp_ch_count;

	if (ppp_is_multilink(dev)) {
		nss_connmgr_pppoe_warn("%px: channel is multilink PPP\n", dev);
		return -1;
	}

	ppp_ch_count = ppp_hold_channels(dev, channel, 1);
	nss_connmgr_pppoe_info("%px: PPP hold channel ret %d\n", dev, ppp_ch_count);
	if (ppp_ch_count != 1) {
		nss_connmgr_pppoe_warn("%px: hold channel for netdevice failed\n", dev);
		return -1;
	}

	px_proto = ppp_channel_get_protocol(channel[0]);
	if (px_proto != PX_PROTO_OE) {
		nss_connmgr_pppoe_warn("%px: session socket is not of type PX_PROTO_OE\n", dev);
		ppp_release_channels(channel, 1);
		return -1;
	}

	if (pppoe_channel_addressing_get(channel[0], addressing)) {
		nss_connmgr_pppoe_warn("%px: failed to get addressing information\n", dev);
		ppp_release_channels(channel, 1);
		return -1;
	}

	dev_put(addressing->dev);
	ppp_release_channels(channel, 1);
	return 0;
}

/*
 * nss_connmgr_add_pppoe_session()
 *	Add PPPoE session entry into Hash table
 */
static struct nss_connmgr_pppoe_session_entry *nss_connmgr_add_pppoe_session(struct net_device *dev, struct pppoe_opt *opt)

{
	struct nss_connmgr_pppoe_session_entry *entry = NULL;
	struct nss_connmgr_pppoe_session_info *info;

	entry = kmalloc(sizeof(struct nss_connmgr_pppoe_session_entry),
				      GFP_KERNEL);
	if (!entry) {
		nss_connmgr_pppoe_warn("%px: failed to allocate pppoe session entry\n", dev);
		return NULL;
	}

	info = &entry->info;

	/*
	 * Get session info
	 */
	info->session_id = (uint16_t)ntohs((uint16_t)opt->pa.sid);
	ether_addr_copy(info->server_mac, opt->pa.remote);
	ether_addr_copy(info->local_mac, opt->dev->dev_addr);

	nss_connmgr_pppoe_info("%px: Added PPPoE session with session_id=%u server_mac=%pM local_mac %pM\n",
			       dev, info->session_id, info->server_mac, info->local_mac);

	entry->dev = dev;

	/*
	 * There is no need for protecting simultaneous addition &
	 * deletion of pppoe sesion entry as the PPP notifier chain
	 * call back is called with mutex lock.
	 */
	hash_add_rcu(pppoe_session_table,
		&entry->hash_list,
		dev->ifindex);

	return entry;
}

/*
 * nss_connmgr_pppoe_disconnect()
 *	pppoe interface's disconnect event handler
 */
static int nss_connmgr_pppoe_disconnect(struct net_device *dev)
{
	struct nss_connmgr_pppoe_session_entry *entry;
	struct nss_connmgr_pppoe_session_entry *found = NULL;
	struct hlist_node *temp;
	struct nss_pppoe_msg npm;
	struct nss_pppoe_destroy_msg *npm_destroy;
	nss_tx_status_t status;
	int if_number;

	/*
	 * check whether the interface is of type PPP
	 */
	if (dev->type != ARPHRD_PPP || !(dev->flags & IFF_POINTOPOINT)) {
		return NOTIFY_DONE;
	}

	/*
	 * Check if pppoe is registered ?
	 */
	if_number = nss_cmn_get_interface_number_by_dev(dev);
	if (if_number < 0) {
		nss_connmgr_pppoe_warn("%px: Net device is not registered with nss\n", dev);
		return NOTIFY_DONE;
	}

	hash_for_each_possible_safe(pppoe_session_table, entry,
				     temp, hash_list, dev->ifindex) {
		if (entry->dev != dev) {
			continue;
		}
		/*
		 * In the hash list, there must be only one entry match with this net device.
		 */
		found = entry;
		break;
	}

	if (!found) {
		nss_connmgr_pppoe_warn("%px: PPPoE session is not found for device: %s\n", dev, dev->name);
		return NOTIFY_DONE;
	}

	hash_del_rcu(&entry->hash_list);
	synchronize_rcu();

	memset(&npm, 0, sizeof(struct nss_pppoe_msg));
	npm_destroy = &npm.msg.destroy;
	npm_destroy->session_id = entry->info.session_id;
	ether_addr_copy(npm_destroy->server_mac, entry->info.server_mac);
	ether_addr_copy(npm_destroy->local_mac, entry->info.local_mac);

	nss_pppoe_msg_init(&npm, if_number, NSS_PPPOE_MSG_SESSION_DESTROY, sizeof(struct nss_pppoe_destroy_msg), NULL, NULL);
	status = nss_pppoe_tx_msg_sync(nss_pppoe_get_context(), &npm);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pppoe_warn("%px: pppoe session destroy command failed, if_number = %d\n", dev, if_number);
		goto done;
	}
	nss_unregister_pppoe_session_if(if_number);
	status = nss_dynamic_interface_dealloc_node(if_number, NSS_DYNAMIC_INTERFACE_TYPE_PPPOE);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pppoe_warn("%px: pppoe dealloc node failure for if_number=%d\n", dev, if_number);
	} else {
		nss_connmgr_pppoe_info("%px: PPPoE session is destroyed with if_number %d, session_id %d, server_mac %pM, local_mac %pM\n",
				       dev, if_number, entry->info.session_id,
				       entry->info.server_mac, entry->info.local_mac);
	}
done:
	kfree(entry);
	return NOTIFY_DONE;
}

/*
 * nss_connmgr_pppoe_connect()
 *	pppoe interface's connect event handler
 */
static int nss_connmgr_pppoe_connect(struct net_device *dev)
{
	struct pppoe_opt opt;
	struct nss_connmgr_pppoe_session_entry *entry = NULL;
	struct nss_connmgr_pppoe_session_info *info;
	nss_tx_status_t status;
	struct nss_ctx_instance *nss_ctx;
	uint32_t features = 0;
	int32_t if_number;
	struct nss_pppoe_msg npm;
	struct nss_pppoe_create_msg *npm_create;
	int ret;

	/*
	 * check whether the interface is of type PPP
	 */
	if (dev->type != ARPHRD_PPP || !(dev->flags & IFF_POINTOPOINT)) {
		return NOTIFY_DONE;
	}

	/*
	 * Check if pppoe is already registered.
	 */
	if_number = nss_cmn_get_interface_number_by_dev(dev);
	if (if_number >= 0) {
		nss_connmgr_pppoe_warn("%px: Net device is already registered with nss\n", dev);
		return NOTIFY_DONE;
	}

	ret = nss_connmgr_pppoe_get_session(dev, &opt);
	if (ret < 0) {
		nss_connmgr_pppoe_warn("%px: Unable to get pppoe session from the netdev\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Create nss dynamic interface and register
	 */
	if_number = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_PPPOE);
	if (if_number == -1) {
		nss_connmgr_pppoe_warn("%px: Request interface number failed\n", dev);
		return NOTIFY_DONE;
	}

	if (!nss_is_dynamic_interface(if_number)) {
		nss_connmgr_pppoe_warn("%px: Invalid NSS dynamic I/F number %d\n", dev, if_number);
		goto connect_fail1;
	}

	nss_connmgr_pppoe_info("%px: PPPoE dynamic interface allocation is successful with if_number %d\n", dev, if_number);

	entry = nss_connmgr_add_pppoe_session(dev, &opt);
	if (!entry) {
		nss_connmgr_pppoe_warn("%px: PPPoE session add failed %d\n", dev, if_number);
		goto connect_fail1;
	}

	/*
	 * Register pppoe  tunnel with NSS
	 */
	nss_ctx = nss_register_pppoe_session_if(if_number,
				       NULL,
				       dev,
				       features,
				       entry);
	if (!nss_ctx) {
		nss_connmgr_pppoe_warn("%px: nss_register_pppoe_session_if failed\n", dev);
		goto connect_fail2;
	}

	nss_connmgr_pppoe_info("%px: PPPoE session interface registration is successful\n", nss_ctx);

	memset(&npm, 0, sizeof(struct nss_pppoe_msg));
	npm_create = &npm.msg.create;
	info = &entry->info;
	npm_create->session_id = info->session_id;

	/*
	 * PPPoE connection could be on a bridge device like br-wan or on bond device like bond0.
	 * So, check if the opt device is bridge or bond.
	 */
	if (netif_is_bond_master(opt.dev)) {
		int32_t bondid = -1;
#if defined(BONDING_SUPPORT)
		bondid = bond_get_id(opt.dev);
#endif
		if (bondid < 0) {
			nss_connmgr_pppoe_warn("%px: Invalid LAG group id 0x%x\n", dev, bondid);
			goto connect_fail3;
		}
		npm_create->base_if_num = bondid + NSS_LAG0_INTERFACE_NUM;
	} else if (opt.dev->priv_flags & IFF_EBRIDGE) {
		/*
		 * Device is bridge. We need to get the actual physical port.
		 * Searching this physical port in the fdb database with the server mac
		 * address of the session.
		 */
		struct net_device *port = br_port_dev_get(opt.dev, info->server_mac, NULL, 0);
		if (!port) {
			nss_connmgr_pppoe_warn("%px: Unable to get the bridge port device from the bridge interface: %s\n",
						dev, opt.dev->name);
			goto connect_fail3;
		}

		/*
		 * Get the interface number of the base interface.
		 */
		npm_create->base_if_num = nss_cmn_get_interface_number_by_dev(port);
		nss_connmgr_pppoe_info("local_mac: %pM server_mac: %pM opt.dev: %s base_if: %d\n",
					info->local_mac, info->server_mac, opt.dev->name, npm_create->base_if_num);
		/*
		 * Release the port which was held by the br_port_dev_get() call.
		 */
		dev_put(port);
	} else {
		/*
		 * PPPoE sessions can be created over either a physical or virtual interface. They may not be
		 * created over a LAG or bridge interface. This interface is the base interface which will be used
		 * for HW next_hop. On SoCs, which do not have HW acceleration, this interface number is not used
		 * and -1 is returned.
		 */
		npm_create->base_if_num = nss_cmn_get_interface_number_by_dev(opt.dev);
	}

	ether_addr_copy(npm_create->server_mac, info->server_mac);
	ether_addr_copy(npm_create->local_mac, info->local_mac);
	npm_create->mtu = dev->mtu;

	nss_connmgr_pppoe_info("%px: pppoe info\n", dev);
	nss_connmgr_pppoe_info("%px: session_id %d server_mac %pM local_mac %pM base_if %s (%d)\n",
			       dev, npm_create->session_id,
			       npm_create->server_mac, npm_create->local_mac, opt.dev->name, npm_create->base_if_num);
	nss_connmgr_pppoe_info("%px: Sending pppoe session create command to NSS\n", dev);

	nss_pppoe_msg_init(&npm, if_number, NSS_PPPOE_MSG_SESSION_CREATE, sizeof(struct nss_pppoe_create_msg), NULL, NULL);

	status = nss_pppoe_tx_msg_sync(nss_ctx, &npm);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pppoe_warn("%px: nss pppoe session creation command error %d\n", dev, status);
		goto connect_fail3;
	}
	nss_connmgr_pppoe_info("%px: PPPoE session creation is successful\n", dev);

	return NOTIFY_DONE;

connect_fail3:
	nss_unregister_pppoe_session_if(if_number);

connect_fail2:
	hash_del_rcu(&entry->hash_list);
	synchronize_rcu();
	kfree(entry);

connect_fail1:
	status = nss_dynamic_interface_dealloc_node(if_number, NSS_DYNAMIC_INTERFACE_TYPE_PPPOE);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pppoe_warn("%px: Unable to dealloc the node[%d] in the NSS fw!\n", dev, if_number);
	}

	return NOTIFY_DONE;
}

/*
 * nss_connmgr_pppoe_channel_notifier_handler()
 *	PPPoE channel notifier handler.
 */
static int nss_connmgr_pppoe_channel_notifier_handler(struct notifier_block *nb,
							unsigned long event,
							void *arg)
{
	struct net_device *dev = (struct net_device *)arg;

	switch (event) {
	case PPP_CHANNEL_CONNECT:
		return nss_connmgr_pppoe_connect(dev);
	case PPP_CHANNEL_DISCONNECT:
		return nss_connmgr_pppoe_disconnect(dev);
	default:
		nss_connmgr_pppoe_info("%px: Unhandled channel event: %lu\n", dev, event);
		break;
	}

	return NOTIFY_DONE;
}

struct notifier_block nss_connmgr_pppoe_channel_notifier_nb = {
        .notifier_call = nss_connmgr_pppoe_channel_notifier_handler,
};

/*
 * nss_connmgr_pppoe_exit_module
 *	pppoe module exit function
 */
void __exit nss_connmgr_pppoe_exit_module(void)
{
#ifdef CONFIG_OF
	/*
	 * If the node is not compatible, don't do anything.
	 */
	if (!of_find_node_by_name(NULL, "nss-common")) {
		return;
	}
#endif

	/*
	 * Unregister the module from the PPP channel events.
	 */
	ppp_channel_connection_unregister_notify(&nss_connmgr_pppoe_channel_notifier_nb);
}

/*
 * nss_connmgr_pppoe_init_module()
 *	pppoe module init function
 */
int __init nss_connmgr_pppoe_init_module(void)
{
#ifdef CONFIG_OF
	/*
	 * If the node is not compatible, don't do anything.
	 */
	if (!of_find_node_by_name(NULL, "nss-common")) {
		return 0;
	}
#endif
	/*
	 * Register the module to the PPP channel events.
	 */
	ppp_channel_connection_register_notify(&nss_connmgr_pppoe_channel_notifier_nb);
	return 0;
}

module_init(nss_connmgr_pppoe_init_module);
module_exit(nss_connmgr_pppoe_exit_module);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("NSS pppoe offload manager");
