/*
 **************************************************************************
 * Copyright (c) 2015-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.
 **************************************************************************
 */

#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/ip.h>
#include <net/ipv6.h>
#include <linux/if_arp.h>
#include <net/route.h>
#include <linux/if_pppox.h>
#include <net/ip.h>

#ifdef CONFIG_OF
#include <linux/of.h>
#endif

#include <nss_api_if.h>
#include <nss_dynamic_interface.h>
#include "nss_connmgr_pptp.h"

#define PPP_HDR_LEN        4

/*
 * NSS pptp debug macros
 */
#if (NSS_PPTP_DEBUG_LEVEL < 1)
#define nss_connmgr_pptp_assert(fmt, args...)
#else
#define nss_connmgr_pptp_assert(c) if (!(c)) { BUG_ON(!(c)); }
#endif

#if defined(CONFIG_DYNAMIC_DEBUG)
/*
 * Compile messages for dynamic enable/disable
 */
#define nss_connmgr_pptp_warning(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define nss_connmgr_pptp_info(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define nss_connmgr_pptp_trace(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else

/*
 * Statically compile messages at different levels
 */
#if (NSS_PPTP_DEBUG_LEVEL < 2)
#define nss_connmgr_pptp_warning(s, ...)
#else
#define nss_connmgr_pptp_warning(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif

#if (NSS_PPTP_DEBUG_LEVEL < 3)
#define nss_connmgr_pptp_info(s, ...)
#else
#define nss_connmgr_pptp_info(s, ...)   pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif

#if (NSS_PPTP_DEBUG_LEVEL < 4)
#define nss_connmgr_pptp_trace(s, ...)
#else
#define nss_connmgr_pptp_trace(s, ...)  pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
#endif

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

static DEFINE_HASHTABLE(pptp_session_table, HASH_BUCKET_SIZE);

/*
 * nss_connmgr_pptp_client_xmit()
 * 	PPTP GRE seq/ack offload callback handler. Sends SKB to NSS firmware.
 * 	Note: RCU lock is already held by caller.
 */
static int nss_connmgr_pptp_client_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct nss_connmgr_pptp_session_entry *session_info;
	struct nss_ctx_instance *nss_pptp_ctx;
	nss_tx_status_t status;
	int host_inner_if;;

	/*
	 * Check if pptp host inner I/F is registered ?
	 */
	host_inner_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER);
	if (host_inner_if < 0) {
		nss_connmgr_pptp_warning("%px: Net device is not registered\n", dev);
		return -1;
	}

	nss_pptp_ctx = nss_pptp_get_context();
	if (!nss_pptp_ctx) {
		nss_connmgr_pptp_warning("%px: NSS PPTP context not found for if_number %d\n", dev, host_inner_if);
		return -1;
	}

	hash_for_each_possible_rcu(pptp_session_table, session_info,
				    hash_list, dev->ifindex) {
		if (session_info->dev != dev) {
			continue;
		}

		status = nss_pptp_tx_buf(nss_pptp_ctx, host_inner_if, skb);
		if (status == NSS_TX_SUCCESS) {
			/*
			 * Found a match for a session and successfully posted
			 * packet to firmware. Retrun success.
			 */
			nss_connmgr_pptp_info("%px: NSS FW tx success if_number %d\n", dev, host_inner_if);
			return 0;
		}

		nss_connmgr_pptp_info("%px: NSS FW tx failed if_number %d\n", dev, host_inner_if);
		return -1;
	}

	/* Return error, Could not find a match for session */
	return -1;
}

/*
 * nss_connmgr_pptp_get_session()
 *	Retrieve pptp session associated with this netdevice if any
 */
static int nss_connmgr_pptp_get_session(struct net_device *dev, struct pptp_opt *opt)
{
	struct ppp_channel *channel[1] = {NULL};
	int px_proto;
	int ppp_ch_count;

	/*
	 * check whether the interface is of type PPP
	 */
	if (dev->type != ARPHRD_PPP || !(dev->priv_flags_ext & IFF_EXT_PPP_PPTP)) {
		nss_connmgr_pptp_info("%px: netdevice is not a PPP tunnel type\n", dev);
		return -1;
	}

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

	if (ppp_is_cp_enabled(dev)) {
		nss_connmgr_pptp_warning("%px: rx or tx compression is enabled for PPP\n", dev);
		return -1;
	}

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

	if (!channel[0]) {
		nss_connmgr_pptp_warning("%px: channel don't have a ppp_channel\n", dev);
		return -1;
	}

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

	pptp_channel_addressing_get(opt, channel[0]);

	ppp_release_channels(channel, 1);
	return 0;
}

/*
 * nss_connmgr_add_pptp_session()
 *	Add PPTP session entry into Hash table
 */
static struct nss_connmgr_pptp_session_entry *nss_connmgr_add_pptp_session(struct net_device *dev, struct pptp_opt *session)

{
	struct nss_connmgr_pptp_session_entry *pptp_session_data = NULL;
	struct nss_connmgr_pptp_session_info *data;
	struct net_device *physical_dev;

	pptp_session_data = kmalloc(sizeof(struct nss_connmgr_pptp_session_entry),
				      GFP_KERNEL);
	if (!pptp_session_data) {
		nss_connmgr_pptp_warning("%px: failed to allocate pptp_session_data\n", dev);
		return NULL;
	}

	data = &pptp_session_data->data;

	/*
	 * Get session info
	 */
	data->src_call = session->src_addr.call_id;
	data->dst_call = session->dst_addr.call_id;
	data->src_ip = session->src_addr.sin_addr.s_addr;
	data->dst_ip = session->dst_addr.sin_addr.s_addr;

	nss_connmgr_pptp_info("%px: src_call_id=%u peer_call_id=%u\n", dev, data->src_call, data->dst_call);

	/*
	 * This netdev hold will be released when netdev
	 * down event arrives and session goes down.
	 */
	dev_hold(dev);
	pptp_session_data->dev = dev;

	/*
	 * Note: ip_dev_find does a hold on the physical device,
	 * which is released when PPTP session goes down
	 */
	physical_dev = ip_dev_find(&init_net, data->src_ip);
	if (!physical_dev) {
		nss_connmgr_pptp_warning("%px: couldn't find a phycal dev %s\n", dev, dev->name);
		dev_put(dev);
		kfree(pptp_session_data);
		return NULL;
	}

	pptp_session_data->phy_dev = physical_dev;

	/*
	 * There is no need for protecting simultaneous addition &
	 * deletion of pptp_session_data as all netdev notifier chain
	 * call back is called with rtln mutex lock.
	 */
	hash_add_rcu(pptp_session_table,
		&pptp_session_data->hash_list,
		dev->ifindex);

	return pptp_session_data;
}

/*
 * nss_connmgr_pptp_event_receive()
 *	Event Callback to receive events from NSS
 */
static void nss_connmgr_pptp_event_receive(void *if_ctx, struct nss_pptp_msg *tnlmsg)
{
	struct nss_connmgr_pptp_session_entry *session_info = (struct nss_connmgr_pptp_session_entry *)if_ctx;
	struct net_device *netdev = session_info->dev;
	struct nss_pptp_sync_session_stats_msg *sync_stats;
	uint32_t if_type;

	switch (tnlmsg->cm.type) {
	case NSS_PPTP_MSG_SYNC_STATS:
		if (!netdev) {
			return;
		}

		nss_connmgr_pptp_info("%px: Update PPP stats for PPTP netdev %px\n", session_info, netdev);
		sync_stats = (struct nss_pptp_sync_session_stats_msg *)&tnlmsg->msg.stats;
		dev_hold(netdev);

		if_type = nss_dynamic_interface_get_type(nss_pptp_get_context(), tnlmsg->cm.interface);

		if (if_type == NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER) {
			ppp_update_stats(netdev,
				 (unsigned long)sync_stats->node_stats.rx_packets,
				 (unsigned long)sync_stats->node_stats.rx_bytes,
				 0, 0, 0, 0, 0, 0);
		} else {

			ppp_update_stats(netdev, 0, 0,
				 (unsigned long)sync_stats->node_stats.tx_packets,
				 (unsigned long)sync_stats->node_stats.tx_bytes,
				  0, 0, 0, 0);
		}

		dev_put(netdev);
		break;

	default:
		nss_connmgr_pptp_warning("%px: Unknown Event from NSS\n", session_info);
		break;
	}
}

/*
 * nss_connmgr_pptp_decap_exception()
 *	Exception handler registered to NSS for handling pptp pkts
 */
static void nss_connmgr_pptp_decap_exception(struct net_device *dev,
				       struct sk_buff *skb,
				       __attribute__((unused)) struct napi_struct *napi)

{
	struct iphdr *iph_outer;
	struct nss_connmgr_pptp_session_entry *session_info;
	struct flowi4 fl4;
	struct nss_pptp_gre_hdr *gre_hdr;
	__be32 tunnel_local_ip;
	__be32 tunnel_peer_ip;
	struct rtable *rt;

	/* discard L2 header */
	skb_pull(skb, sizeof(struct ethhdr));
	skb_reset_mac_header(skb);

	iph_outer = (struct iphdr *)skb->data;

	rcu_read_lock();
	hash_for_each_possible_rcu(pptp_session_table, session_info,
				   hash_list, dev->ifindex) {
		if (session_info->dev != dev) {
			continue;
		}

		tunnel_local_ip = session_info->data.src_ip;
		tunnel_peer_ip = session_info->data.dst_ip;
		rcu_read_unlock();
		if ((iph_outer->version == 4) && (iph_outer->protocol == IPPROTO_GRE) &&
			(iph_outer->saddr == tunnel_local_ip) && (iph_outer->daddr == tunnel_peer_ip)) { /*pkt is encapsulated */

			/*
			 * Pull the outer IP header and confirm the packet is a PPTP GRE Packet
			 */
			skb_pull(skb, sizeof(struct iphdr));
			gre_hdr = (struct nss_pptp_gre_hdr *)skb->data;
			if ((ntohs(gre_hdr->protocol) != NSS_PPTP_GRE_PROTO) &&
				(gre_hdr->flags_ver == NSS_PPTP_GRE_VER)) {
				nss_connmgr_pptp_warning("%px, Not PPTP_GRE_PROTO, so freeing\n", dev);
				dev_kfree_skb_any(skb);
				return;
			}

			skb_push(skb, sizeof(struct iphdr));

			/*
			 * This is a PPTP encapsulated packet that has been exceptioned to host from NSS.
			 * We can send it directly to the physical device
			 */
			rt = ip_route_output_ports(&init_net, &fl4, NULL, tunnel_peer_ip,
					tunnel_local_ip, 0, 0, IPPROTO_GRE, RT_TOS(0), 0);
			if (unlikely(IS_ERR(rt))) {
				nss_connmgr_pptp_warning("%px: Martian packets, drop\n", dev);
				nss_connmgr_pptp_warning("%px: No route or out dev, drop packet...\n", dev);
				dev_kfree_skb_any(skb);
				return;
			}

			if (likely(rt->dst.dev)) {
				nss_connmgr_pptp_info("%px: dst route dev is %s\n", session_info, rt->dst.dev->name);
			} else {
				nss_connmgr_pptp_warning("%px: No out dev, drop packet...\n", dev);
				dev_kfree_skb_any(skb);
			}

			/*
			 * Sets the 'dst' entry for SKB, reset the IP and Transport
			 * Header and sends the packet out directly to the physical
			 * device associated with the PPTP tunnel interface.
			 */
			skb->dev = dev;
			skb_dst_drop(skb);
			skb_dst_set(skb, &rt->dst);
			skb->ip_summed = CHECKSUM_COMPLETE;

			skb_reset_network_header(skb);
			skb_set_transport_header(skb, iph_outer->ihl*4);
			skb->skb_iif = dev->ifindex;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
			ip_local_out(skb);
#else
			ip_local_out(&init_net, skb->sk, skb);
#endif
			return;
		}
	}
	rcu_read_unlock();
	nss_connmgr_pptp_warning("%px: unable to find session for PPTP exception packet from %s, so freeing\n", dev, dev->name);
	dev_kfree_skb_any(skb);
}

/*
 * nss_connmgr_pptp_encap_exception()
 *	Exception handler registered to NSS for handling pptp pkts
 */
static void nss_connmgr_pptp_encap_exception(struct net_device *dev,
				       struct sk_buff *skb,
				       __attribute__((unused)) struct napi_struct *napi)

{
	struct iphdr *iph_outer;
	struct nss_connmgr_pptp_session_entry *session_info;
	__be32 tunnel_local_ip;
	__be32 tunnel_peer_ip;

	/* discard L2 header */
	skb_pull(skb, sizeof(struct ethhdr));
	skb_reset_mac_header(skb);

	iph_outer = (struct iphdr *)skb->data;

	rcu_read_lock();
	hash_for_each_possible_rcu(pptp_session_table, session_info,
				   hash_list, dev->ifindex) {
		if (session_info->dev != dev) {
			continue;
		}

		tunnel_local_ip = session_info->data.src_ip;
		tunnel_peer_ip = session_info->data.dst_ip;
		rcu_read_unlock();

		if (iph_outer->version == 4) {
			skb->protocol = htons(ETH_P_IP);
		} else if (iph_outer->version == 6) {
			skb->protocol = htons(ETH_P_IPV6);
		} else {
			nss_connmgr_pptp_info("%px: pkt may be a control packet\n", dev);
		}

		skb_reset_network_header(skb);
		skb->pkt_type = PACKET_HOST;
		skb->skb_iif = dev->ifindex;
		skb->ip_summed = CHECKSUM_NONE;
		skb->dev = dev;
		nss_connmgr_pptp_info("%px: send decapsulated packet through network stack", dev);
		netif_receive_skb(skb);
		return;
	}
	rcu_read_unlock();
	nss_connmgr_pptp_warning("%px: unable to find session for PPTP exception packet from %s, so freeing\n", dev, dev->name);
	dev_kfree_skb_any(skb);
}

/*
 * nss_connmgr_pptp_dev_up()
 *	pppopptp interface's up event handler
 */
static int nss_connmgr_pptp_dev_up(struct net_device *dev)
{
	struct pptp_opt opt;
	struct nss_connmgr_pptp_session_entry *session_info = NULL;
	struct nss_connmgr_pptp_session_info *data;
	nss_tx_status_t status;
	struct nss_ctx_instance *nss_ctx;
	uint32_t features = 0;
	int32_t inner_if, outer_if, host_inner_if;
	struct nss_pptp_msg  pptpmsg;
	struct nss_pptp_session_configure_msg *pptpcfg;
	int ret;

	ret = nss_connmgr_pptp_get_session(dev, &opt);
	if (ret < 0) {
		return NOTIFY_DONE;
	}

	/*
	 * Create nss dynamic interface and register
	 */
	inner_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER);
	if (inner_if < 0) {
		nss_connmgr_pptp_warning("%px: Request inner interface number failed\n", dev);
		return NOTIFY_DONE;
	}

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

	outer_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER);
	if (outer_if < 0) {
		nss_connmgr_pptp_warning("%px: Request outer interface number failed\n", dev);
		goto inner_fail;
	}

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

	host_inner_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER);
	if (host_inner_if < 0) {
		nss_connmgr_pptp_warning("%px: Request host inner interface number failed\n", dev);
		goto outer_fail;
	}

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

	session_info = nss_connmgr_add_pptp_session(dev, &opt);
	if (!session_info) {
		nss_connmgr_pptp_warning("%px: PPTP session add failed\n", dev);
		goto host_inner_fail;
	}

	/*
	 * Register pptp tunnel inner interface with NSS
	 */
	nss_ctx = nss_register_pptp_if(inner_if,
				NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER,
				nss_connmgr_pptp_encap_exception,
				nss_connmgr_pptp_event_receive,
				dev,
				features,
				session_info);

	if (!nss_ctx) {
		nss_connmgr_pptp_warning("%px: nss_register_pptp_if failed for inner\n", dev);
		goto register_inner_if_fail;
	}

	nss_connmgr_pptp_info("%px: inner interface registration successful\n", nss_ctx);

	/*
	 * Register pptp tunnel outer interface with NSS
	 */
	nss_ctx = nss_register_pptp_if(outer_if,
				NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER,
				nss_connmgr_pptp_decap_exception,
				nss_connmgr_pptp_event_receive,
				dev,
				features,
				session_info);

	if (!nss_ctx) {
		nss_connmgr_pptp_warning("%px: nss_register_pptp_if failed for outer\n", dev);
		goto register_outer_if_fail;
	}

	nss_connmgr_pptp_info("%px: outer interface registration successful\n", nss_ctx);

	/*
	 * Register pptp tunnel inner interface with NSS
	 */
	nss_ctx = nss_register_pptp_if(host_inner_if,
				NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER,
				nss_connmgr_pptp_encap_exception,
				nss_connmgr_pptp_event_receive,
				dev,
				features,
				session_info);

	if (!nss_ctx) {
		nss_connmgr_pptp_warning("%px: nss_register_pptp_if failed for host inner\n", dev);
		goto register_host_inner_if_fail;
	}

	nss_connmgr_pptp_info("%px: host inner interface registration successful\n", nss_ctx);

	/*
	 * Initialize and configure inner I/F.
	 */
	data = &session_info->data;

	memset(&pptpmsg, 0, sizeof(struct nss_pptp_msg));
	pptpcfg = &pptpmsg.msg.session_configure_msg;

	/*
	 * The call id is already in host byte order,
	 * therefore no need to do ntohs() for call id.
	 */
	pptpcfg->src_call_id = data->src_call;
	pptpcfg->dst_call_id = data->dst_call;

	/*
	 * Convert IP addresses from nework byte order
	 * to host byte order before posting to firmware.
	 */
	pptpcfg->sip = ntohl(data->src_ip);
	pptpcfg->dip = ntohl(data->dst_ip);

	/*
	 * Populate the sibling interfaces.
	 */
	pptpcfg->sibling_ifnum_pri = outer_if;
	pptpcfg->sibling_ifnum_aux = host_inner_if;

	nss_connmgr_pptp_info("%px: pptp info\n", dev);
	nss_connmgr_pptp_info("%px: local_call_id %d peer_call_id %d\n", dev,
									pptpcfg->src_call_id,
									pptpcfg->dst_call_id);
	nss_connmgr_pptp_info("%px: saddr 0x%x daddr 0x%x \n", dev, pptpcfg->sip, pptpcfg->dip);

	nss_pptp_msg_init(&pptpmsg, inner_if, NSS_PPTP_MSG_SESSION_CONFIGURE, sizeof(struct nss_pptp_session_configure_msg), NULL, NULL);

	status = nss_pptp_tx_msg_sync(nss_ctx, &pptpmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: nss pptp session creation command error %d\n", dev, status);
		goto tx_msg_fail;
	}
	nss_connmgr_pptp_info("%px: nss_pptp_tx() successful for inner\n", dev);

	/*
	 * Initialize and configure outer I/F.
	 */
	pptpcfg->sibling_ifnum_pri = inner_if;
	pptpcfg->sibling_ifnum_aux = host_inner_if;

	nss_pptp_msg_init(&pptpmsg, outer_if, NSS_PPTP_MSG_SESSION_CONFIGURE, sizeof(struct nss_pptp_session_configure_msg), NULL, NULL);

	status = nss_pptp_tx_msg_sync(nss_ctx, &pptpmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: nss pptp session creation command error %d\n", dev, status);
		goto tx_msg_fail;
	}
	nss_connmgr_pptp_info("%px: nss_pptp_tx() successful for outer\n", dev);

	/*
	 * Initialize and configure host inner I/F.
	 */
	pptpcfg->sibling_ifnum_pri = outer_if;
	pptpcfg->sibling_ifnum_aux = inner_if;

	nss_pptp_msg_init(&pptpmsg, host_inner_if, NSS_PPTP_MSG_SESSION_CONFIGURE, sizeof(struct nss_pptp_session_configure_msg), NULL, NULL);

	status = nss_pptp_tx_msg_sync(nss_ctx, &pptpmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: nss pptp session creation command error %d\n", dev, status);
		goto tx_msg_fail;
	}
	nss_connmgr_pptp_info("%px: nss_pptp_tx() successful for host inner\n", dev);

	/*
	 * Enable the offload mode for Linux PPTP kernel driver. After this
	 * all PPTP GRE packets will go through the NSS FW.
	 */
	pptp_session_enable_offload_mode(data->dst_call, data->dst_ip);

	return NOTIFY_DONE;

tx_msg_fail:
	nss_unregister_pptp_if(host_inner_if);
register_host_inner_if_fail:
	nss_unregister_pptp_if(outer_if);
register_outer_if_fail:
	nss_unregister_pptp_if(inner_if);
register_inner_if_fail:
		dev_put(dev); /* We are accessing dev later */
		dev_put(session_info->phy_dev);
		hash_del_rcu(&session_info->hash_list);
		synchronize_rcu();
		kfree(session_info);
host_inner_fail:
	status = nss_dynamic_interface_dealloc_node(host_inner_if, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: Unable to dealloc the node[%d] in the NSS fw!\n", dev, host_inner_if);
	}
outer_fail:
	status = nss_dynamic_interface_dealloc_node(inner_if, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: Unable to dealloc the node[%d] in the NSS fw!\n", dev, outer_if);
	}
inner_fail:
	status = nss_dynamic_interface_dealloc_node(inner_if, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: Unable to dealloc the node[%d] in the NSS fw!\n", dev, inner_if);
	}

	return NOTIFY_DONE;
}

/*
 * nss_connmgr_pptp_dev_down()
 *	pptp interface's down event handler
 */
static int nss_connmgr_pptp_dev_down(struct net_device *dev)
{
	struct nss_connmgr_pptp_session_entry *session_info;
	struct nss_connmgr_pptp_session_entry *session_found = NULL;
	struct hlist_node *tmp;

	struct nss_pptp_msg pptpmsg;
	struct nss_pptp_session_deconfigure_msg *pptpcfg;
	nss_tx_status_t status;
	int32_t inner_if, outer_if, host_inner_if;

	/*
	 * check whether the interface is of type PPP
	 */
	if (dev->type != ARPHRD_PPP || !(dev->priv_flags_ext & IFF_EXT_PPP_PPTP)) {
		nss_connmgr_pptp_info("%px: netdevice is not a pptp tunnel type\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Check if pptp inner I/F is registered ?
	 */
	inner_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER);
	if (inner_if < 0) {
		nss_connmgr_pptp_warning("%px: outer I/F is not registered\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Check if pptp outer I/F is registered ?
	 */
	outer_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER);
	if (outer_if < 0) {
		nss_connmgr_pptp_warning("%px: inner I/F is not registered\n", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Check if pptp host inner I/F is registered ?
	 */
	host_inner_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER);
	if (host_inner_if < 0) {
		nss_connmgr_pptp_warning("%px: Net device is not registered\n", dev);
		return NOTIFY_DONE;
	}

	hash_for_each_possible_safe(pptp_session_table, session_info,
				    tmp, hash_list, dev->ifindex) {
		if (session_info->dev != dev) {
			continue;
		}

		session_found = session_info;
		break;
	}

	if (!session_found) {
		nss_connmgr_pptp_warning("%px: pptp session is not found for this device", dev);
		return NOTIFY_DONE;
	}

	/*
	 * Disable the pptp offload mode. This will allow all PPTP GRE packets
	 * to go through linux PPTP kernel module.
	 */
	pptp_session_disable_offload_mode(session_info->data.dst_call, session_info->data.dst_ip);
	dev_put(dev);
	dev_put(session_info->phy_dev);
	hash_del_rcu(&session_info->hash_list);
	synchronize_rcu();

	memset(&pptpmsg, 0, sizeof(struct nss_pptp_msg));
	pptpcfg = &pptpmsg.msg.session_deconfigure_msg;
	pptpcfg->src_call_id = session_info->data.src_call;

	/*
	 * Deconfigure all I/Fs.
	 */
	nss_pptp_msg_init(&pptpmsg, inner_if, NSS_PPTP_MSG_SESSION_DECONFIGURE, sizeof(struct nss_pptp_session_deconfigure_msg), NULL, NULL);
	status = nss_pptp_tx_msg_sync(nss_pptp_get_context(), &pptpmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: pptp session destroy command failed, if_number = %d\n", dev, inner_if);
		goto fail;
	}

	nss_pptp_msg_init(&pptpmsg, outer_if, NSS_PPTP_MSG_SESSION_DECONFIGURE, sizeof(struct nss_pptp_session_deconfigure_msg), NULL, NULL);
	status = nss_pptp_tx_msg_sync(nss_pptp_get_context(), &pptpmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: pptp session destroy command failed, if_number = %d\n", dev, outer_if);
		goto fail;
	}

	nss_pptp_msg_init(&pptpmsg, host_inner_if, NSS_PPTP_MSG_SESSION_DECONFIGURE, sizeof(struct nss_pptp_session_deconfigure_msg), NULL, NULL);
	status = nss_pptp_tx_msg_sync(nss_pptp_get_context(), &pptpmsg);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: pptp session destroy command failed, if_number = %d\n", dev, host_inner_if);
		goto fail;
	}

	/*
	 * Unregister all the I/Fs.
	 */
	nss_unregister_pptp_if(inner_if);
	nss_unregister_pptp_if(outer_if);
	nss_unregister_pptp_if(host_inner_if);

	/*
	 * Dealloc all the I/Fs.
	 */
	status = nss_dynamic_interface_dealloc_node(inner_if, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: pptp dealloc node failure for inner if_number=%d\n", dev, inner_if);
		goto fail;
	}

	status = nss_dynamic_interface_dealloc_node(outer_if, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: pptp dealloc node failure for outer if_number=%d\n", dev, outer_if);
		goto fail;
	}

	status = nss_dynamic_interface_dealloc_node(host_inner_if, NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER);
	if (status != NSS_TX_SUCCESS) {
		nss_connmgr_pptp_warning("%px: pptp dealloc node failure for host inner if_number=%d\n", dev, host_inner_if);
		goto fail;
	}

	nss_connmgr_pptp_info("%px: deleting pptpsession, if_number %d, local_call_id %d, peer_call_id %d\n", dev,
					dev->ifindex, session_info->data.src_call,  session_info->data.dst_call);

fail:
	kfree(session_info);
	return NOTIFY_DONE;

}

/*
 * nss_connmgr_pptp_dev_event()
 *	Net device notifier for nss pptp module
 */
static int nss_connmgr_pptp_dev_event(struct notifier_block  *nb,
		unsigned long event, void  *dev)
{
	struct net_device *netdev = netdev_notifier_info_to_dev(dev);

	switch (event) {
	case NETDEV_UP:
		nss_connmgr_pptp_info("%px: netdevice '%s' UP event\n", netdev, netdev->name);
		return nss_connmgr_pptp_dev_up(netdev);

	case NETDEV_DOWN:
		nss_connmgr_pptp_info("%px: netdevice '%s' Down event\n", netdev, netdev->name);
		return nss_connmgr_pptp_dev_down(netdev);

	default:
		break;
	}

	return NOTIFY_DONE;
}

/*
 * Linux Net device Notifier
 */
struct notifier_block nss_connmgr_pptp_notifier = {
	.notifier_call = nss_connmgr_pptp_dev_event,
};

/*
 * nss_connmgr_pptp_init_module()
 *	Tunnel pptp module init function
 */
int __init nss_connmgr_pptp_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_netdevice_notifier(&nss_connmgr_pptp_notifier);
	pptp_register_gre_seq_offload_callback(nss_connmgr_pptp_client_xmit);
	return 0;
}

/*
 * nss_connmgr_pptp_exit_module
 *	Tunnel pptp module exit function
 */
void __exit nss_connmgr_pptp_exit_module(void)
{
	pptp_unregister_gre_seq_offload_callback();
#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_netdevice_notifier(&nss_connmgr_pptp_notifier);
}

module_init(nss_connmgr_pptp_init_module);
module_exit(nss_connmgr_pptp_exit_module);

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