[qca-nss-clients] Enabling netlink IPsec Module

Enabling netlink IPsec Module
Adding some bug fixes also.
Addressing qca swnbu errors

Change-Id: Ib4e3af8bd1a7aa6ec63ccf42630b7bc28462ca78
Signed-off-by: mandrw <mandrw@codeaurora.org>
diff --git a/netlink/Makefile b/netlink/Makefile
index 15fd740..a36ff75 100755
--- a/netlink/Makefile
+++ b/netlink/Makefile
@@ -11,6 +11,6 @@
 qca-nss-netlink-objs := nss_nl.o
 qca-nss-netlink-objs += nss_nlcrypto.o
 qca-nss-netlink-objs += nss_nlipv4.o
-#qca-nss-netlink-objs += nss_nlipsec.o
+qca-nss-netlink-objs += nss_nlipsec.o
 
 
diff --git a/netlink/include/nss_nl_if.h b/netlink/include/nss_nl_if.h
index 270a948..d812133 100755
--- a/netlink/include/nss_nl_if.h
+++ b/netlink/include/nss_nl_if.h
@@ -26,10 +26,6 @@
 #define NSS_NL_VER_SHIFT 8
 
 #define NSS_NL_VER ((NSS_NL_VER_MAJOR << NSS_NL_VER_SHIFT) | NSS_NL_VER_MINOR)
-#define NSS_NL_CMD_TIMEOUT_MS 4000 /* msecs */
-
-#include "nss_nlcmn_if.h"
-#include "nss_nlipv4_if.h"
 
 #endif /* __NSS_NL_IF_H */
 
diff --git a/netlink/nss_nl.c b/netlink/nss_nl.c
index 021effb..1cfc2fe 100755
--- a/netlink/nss_nl.c
+++ b/netlink/nss_nl.c
@@ -24,9 +24,17 @@
 
 #include <nss_api_if.h>
 #include <nss_nl_if.h>
+#include "nss_ipsecmgr.h"
+#include "nss_nlcmn_if.h"
+#include "nss_crypto_if.h"
+#include "nss_nlipv4_if.h"
+#include "nss_nlcrypto_if.h"
+#include "nss_nlipsec_if.h"
 
 #include "nss_nl.h"
 #include "nss_nlipv4.h"
+#include "nss_nlcrypto.h"
+#include "nss_nlipsec.h"
 
 /*
  * nss_nl.c
@@ -47,7 +55,6 @@
  * Family handler table
  */
 static struct nss_nl_family family_handlers[] = {
-#if 0
 	{
 		/*
 		 * NSS_NLCRYPTO
@@ -57,7 +64,6 @@
 		.exit = NSS_NLCRYPTO_EXIT,		/* exit */
 		.valid = CONFIG_NSS_NLCRYPTO		/* 1 or 0 */
 	},
-#endif
 	{
 		/*
 		 * NSS_NLIPV4
@@ -67,7 +73,6 @@
 		.exit = NSS_NLIPV4_EXIT,		/* exit */
 		.valid = CONFIG_NSS_NLIPV4		/* 1 or 0 */
 	},
-#if 0
 	{
 		/*
 		 * NSS_NLIPSEC
@@ -77,8 +82,6 @@
 		.exit = NSS_NLIPSEC_EXIT,		/* exit */
 		.valid = CONFIG_NSS_NLIPSEC		/* 1 or 0 */
 	},
-#endif
-
 };
 
 #define NSS_NL_FAMILY_HANDLER_SZ ARRAY_SIZE(family_handlers)
diff --git a/netlink/nss_nlcrypto.c b/netlink/nss_nlcrypto.c
index 9f793d0..e9c0a29 100644
--- a/netlink/nss_nlcrypto.c
+++ b/netlink/nss_nlcrypto.c
@@ -23,6 +23,8 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/version.h>
+
+#include <nss_crypto_if.h>
 #include <linux/netlink.h>
 #include <linux/version.h>
 #include <net/genetlink.h>
@@ -30,18 +32,25 @@
 #include <nss_api_if.h>
 #include <nss_cmn.h>
 #include <nss_nl_if.h>
-#include "nss_nl.h"
-#include <nss_crypto_if.h>
+#include "nss_nlcmn_if.h"
+#include "nss_crypto_if.h"
 #include "nss_nlcrypto_if.h"
+#include "nss_nl.h"
+
 /*
  * @brief prototypes
  */
-
 static int nss_nlcrypto_op_session_create(struct sk_buff *skb_msg, struct genl_info *info);
 static int nss_nlcrypto_op_session_update(struct sk_buff *skb_msg, struct genl_info *info);
 static int nss_nlcrypto_op_session_destroy(struct sk_buff *skb_msg, struct genl_info *info);
 static int nss_nlcrypto_op_session_info(struct sk_buff *skb_msg, struct genl_info *info);
 
+/*
+ * NSS NETLINK crypto context
+ */
+struct nss_nlcrypto_ctx {
+	nss_crypto_handle_t crypto_hdl;
+};
 
 /*
  * @brief  Crypto family definition
@@ -70,11 +79,6 @@
 
 #define NSS_NLCRYPTO_OPS_SZ ARRAY_SIZE(nss_nlcrypto_ops)
 
-static nss_crypto_handle_t nss_nlcrypto_hdl;
-
-struct nss_nlcrypto_ctx {
-	nss_crypto_handle_t crypto_hdl;		/* Crypto handle */
-};
 
 /*
  * global context
@@ -167,15 +171,16 @@
 	/* pure decryption */
 	case NSS_CRYPTO_REQ_TYPE_DECRYPT:
 		return true;
-	/* encryption + authentication */
+	/* encryption and authentication */
 	case (NSS_CRYPTO_REQ_TYPE_ENCRYPT | NSS_CRYPTO_REQ_TYPE_AUTH):
 		return true;
-	/* decryption + authentication */
+	/* decryption and authentication */
 	case (NSS_CRYPTO_REQ_TYPE_DECRYPT | NSS_CRYPTO_REQ_TYPE_AUTH):
 		return true;
-	/* everything else */
+	/* otherwise */
 	default:
 		return false;
+
 	}
 
 	return false;
@@ -209,8 +214,6 @@
 	struct sk_buff *resp;
 	uint32_t pid;
 
-
-
 	/*
 	 * extract the message payload
 	 */
@@ -329,7 +332,7 @@
 		return -EINVAL;
 	}
 
-	return nss_crypto_session_update(nss_nlcrypto_hdl, session_idx, param);
+	return nss_crypto_session_update(gbl_ctx.crypto_hdl, session_idx, param);
 }
 
 /*
@@ -372,7 +375,7 @@
 		return -EINVAL;
 	}
 
-	status = nss_crypto_session_free(nss_nlcrypto_hdl, destroy->session_idx);
+	status = nss_crypto_session_free(gbl_ctx.crypto_hdl, destroy->session_idx);
 	if (status != NSS_CRYPTO_STATUS_OK) {
 		nss_nl_error("unable to delete the session:%d\n", destroy->session_idx);
 		return -EINVAL;
@@ -507,7 +510,7 @@
 		return false;
 	}
 
-	nss_crypto_unregister_user(nss_nlcrypto_hdl);
+	nss_crypto_unregister_user(gbl_ctx.crypto_hdl);
 
 	return true;
 }
diff --git a/netlink/nss_nlcrypto.h b/netlink/nss_nlcrypto.h
new file mode 100644
index 0000000..43edd8b
--- /dev/null
+++ b/netlink/nss_nlcrypto.h
@@ -0,0 +1,36 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2014 - 2015, 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_nlcrypto.h
+ *	NSS Netlink Crypto API definitions
+ */
+#ifndef __NSS_NLCRYPTO_H
+#define __NSS_NLCRYPTO_H
+
+
+bool nss_nlcrypto_init(void);
+bool nss_nlcrypto_exit(void);
+
+#if defined(CONFIG_NSS_NLCRYPTO)
+#define NSS_NLCRYPTO_INIT nss_nlcrypto_init
+#define NSS_NLCRYPTO_EXIT nss_nlcrypto_exit
+#else
+#define NSS_NLCRYPTO_INIT 0
+#define NSS_NLCRYPTO_EXIT 0
+#endif /* !CONFIG_NSS_NLCRYPTO */
+
+#endif /* __NSS_NLCRYPTO_H */
diff --git a/netlink/nss_nlipsec.c b/netlink/nss_nlipsec.c
index 33f11cf..2ff71c9 100644
--- a/netlink/nss_nlipsec.c
+++ b/netlink/nss_nlipsec.c
@@ -35,10 +35,10 @@
 #include <nss_cmn.h>
 #include <nss_ipsec.h>
 #include <nss_ipsecmgr.h>
-#include <nss_crypto.h>
-#include "nss_crypto_if.h"
 #include <nss_nl_if.h>
+#include "nss_crypto_if.h"
 #include "nss_nl.h"
+#include "nss_nlcmn_if.h"
 #include "nss_nlipsec_if.h"
 
 
diff --git a/netlink/nss_nlipsec.h b/netlink/nss_nlipsec.h
new file mode 100644
index 0000000..bfdafd2
--- /dev/null
+++ b/netlink/nss_nlipsec.h
@@ -0,0 +1,36 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2014 - 2015, 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_nlipsec.h
+ *	NSS Netlink IPsec API definitions
+ */
+#ifndef __NSS_NLIPSEC_H
+#define __NSS_NLIPSEC_H
+
+
+bool nss_nlipsec_init(void);
+bool nss_nlipsec_exit(void);
+
+#if defined(CONFIG_NSS_NLIPSEC)
+#define NSS_NLIPSEC_INIT nss_nlipsec_init
+#define NSS_NLIPSEC_EXIT nss_nlipsec_exit
+#else
+#define NSS_NLIPSEC_INIT 0
+#define NSS_NLIPSEC_EXIT 0
+#endif /* !CONFIG_NSS_NLIPSEC */
+
+#endif /* __NSS_NLIPSEC_H */
diff --git a/netlink/nss_nlipv4.c b/netlink/nss_nlipv4.c
index a1cbbb4..6e883a2 100755
--- a/netlink/nss_nlipv4.c
+++ b/netlink/nss_nlipv4.c
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/version.h>
 #include <linux/if.h>
+#include <linux/in.h>
 #include <linux/netlink.h>
 #include <linux/rcupdate.h>
 #include <linux/etherdevice.h>
@@ -44,9 +45,10 @@
 
 #include <nss_api_if.h>
 #include <nss_cmn.h>
-#include <nss_ipsec.h>
 #include <nss_nl_if.h>
 #include "nss_nl.h"
+#include "nss_nlcmn_if.h"
+#include "nss_nlipv4_if.h"
 
 
 #define NSS_NLIPV4_ARPHRD_IPSEC_TUNNEL_TYPE 0x31
@@ -236,25 +238,30 @@
 static int nss_nlipv4_verify_5tuple(struct nss_ipv4_rule_create_msg *msg)
 {
 	struct nss_ipv4_5tuple *tuple = &msg->tuple;
+	bool ident_check = false;
 
 	/*
-	 * protocol must be provided
+	 * protocol, flow ip and return ip  must be provided
 	 */
-	if (!tuple->protocol) {
-		nss_nl_info("Empty protocol for 5-tuple\n");
+	if (!tuple->protocol || !tuple->flow_ip || !tuple->return_ip) {
+		nss_nl_info("Empty protocol or flow_ip or return_ip for 5-tuple\n");
 		return -EINVAL;
 	}
 
-	/*
-	 * flow or return should not be empty
-	 */
-	if (!tuple->flow_ip || !tuple->flow_ident) {
-		nss_nl_info("Empty flow info ip:%d, port:%d\n", tuple->flow_ip, tuple->flow_ident);
-		return -EINVAL;
+	/* Validate the port number */
+	switch (tuple->protocol) {
+	case IPPROTO_UDP:
+	case IPPROTO_TCP:
+	case IPPROTO_SCTP:
+		ident_check = true;
+		break;
+	default:
+		ident_check = false;
+		break;
 	}
 
-	if (!tuple->return_ip || !tuple->return_ident) {
-		nss_nl_info("Empty flow info ip:%d, port:%d\n", tuple->return_ip, tuple->return_ident);
+	if (ident_check && (!tuple->flow_ident || !tuple->return_ident)) {
+		nss_nl_info("Empty idents flow port:%d return port:%d\n", tuple->flow_ident, tuple->return_ident);
 		return -EINVAL;
 	}
 
@@ -674,6 +681,7 @@
 	struct nss_nlcmn *nl_cm;
 	struct nss_ipv4_msg *nim;
 	nss_tx_status_t tx_status;
+	struct sk_buff *resp;
 	uint32_t pid;
 	int error;
 
@@ -703,6 +711,15 @@
 	}
 
 	/*
+	 * copy the NL message for response
+	 */
+	resp = nss_nl_copy_msg(skb);
+	if (!resp) {
+		nss_nl_error("%d:unable to save response data from NL buffer\n", pid);
+		error = -ENOMEM;
+		goto done;
+	}
+	/*
 	 * Initialize the common message
 	 */
 	nss_ipv4_msg_init(nim,						/* ipv4 message */
@@ -710,7 +727,7 @@
 			NSS_IPV4_TX_DESTROY_RULE_MSG,			/* rule */
 			sizeof(struct nss_ipv4_rule_destroy_msg),	/* message size */
 			nss_nlipv4_process_resp,			/* response callback */
-			(void *)nim);					/* app context */
+			(void *)resp);					/* app context */
 
 	/*
 	 * Push rule to NSS