Merge "[qca-nss-drv] Provision ipv4 and ipv6 to send back create rule responses" into banana_n2h
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index 983420f..6103fd8 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -461,6 +461,8 @@
 	NSS_IPV4_CB_REASON_ESTABLISH = 0,
 					/**< Reason is rule establish */
 	NSS_IPV4_CB_REASON_SYNC,	/**< Reason is rule sync */
+	NSS_IPV4_CB_REASON_ESTABLISH_FAIL,
+					/**< Reason is rule establish failes */
 };
 
 /**
@@ -553,6 +555,8 @@
 	NSS_IPV6_CB_REASON_ESTABLISH = 0,
 					/**< Reason is rule establish */
 	NSS_IPV6_CB_REASON_SYNC,	/**< Reason is rule sync */
+	NSS_IPV6_CB_REASON_ESTABLISH_FAIL,
+					/**< Reason is rule establish failes */
 };
 
 /**
diff --git a/nss_ipv4.c b/nss_ipv4.c
index 03fad80..f9edfc8 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -22,6 +22,7 @@
 #include "nss_tx_rx_common.h"
 
 extern void nss_rx_metadata_ipv4_rule_establish(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_rule_establish *nire);
+extern void nss_rx_metadata_ipv4_create_response(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim);
 extern void nss_rx_ipv4_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync *nirs);
 
 /*
@@ -151,6 +152,10 @@
 		nss_ipv4_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
 		nss_rx_ipv4_sync(nss_ctx, &nim->msg.conn_stats);
 		break;
+
+	case NSS_IPV4_TX_CREATE_RULE_MSG:
+		nss_rx_metadata_ipv4_create_response(nss_ctx, nim);
+		break;
 	}
 
 	/*
diff --git a/nss_ipv6.c b/nss_ipv6.c
index d8a96e5..0143faf 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -22,6 +22,7 @@
 #include "nss_tx_rx_common.h"
 
 extern void nss_rx_metadata_ipv6_rule_establish(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_rule_establish *nire);
+extern void nss_rx_metadata_ipv6_create_response(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim);
 extern void nss_rx_ipv6_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nirs);
 
 /*
@@ -152,6 +153,10 @@
 		nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
 		return nss_rx_ipv6_sync(nss_ctx, &nim->msg.conn_stats);
 		break;
+
+	case NSS_IPV6_TX_CREATE_RULE_MSG:
+		nss_rx_metadata_ipv6_create_response(nss_ctx, nim);
+		break;
 	}
 
 	/*
diff --git a/nss_tx_rx_ipv4.c b/nss_tx_rx_ipv4.c
index 12539df..698ac65 100644
--- a/nss_tx_rx_ipv4.c
+++ b/nss_tx_rx_ipv4.c
@@ -149,6 +149,47 @@
 }
 
 /*
+ * nss_rx_metadata_ipv4_create_response()
+ *	Handle the ACK/NACK for IPv4 create rule.
+ */
+void nss_rx_metadata_ipv4_create_response(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim)
+{
+	struct nss_ipv4_cb_params nicp;
+	nss_ipv4_callback_t cb;
+	struct nss_ipv4_rule_create_msg *nircm;
+	struct nss_ipv4_establish *nie;
+
+	if (nim->cm.response == NSS_CMN_RESPONSE_ACK) {
+		return;
+	}
+
+	nicp.reason = NSS_IPV4_CB_REASON_ESTABLISH_FAIL;
+
+	nircm = &nim->msg.rule_create;
+	nie = &nicp.params.establish;
+
+	nie->protocol = nircm->tuple.protocol;
+	nie->flow_ip = nircm->tuple.flow_ip;
+	nie->flow_ip_xlate = nircm->conn_rule.flow_ip_xlate;
+	nie->flow_ident = nircm->tuple.flow_ident;
+	nie->flow_ident_xlate = nircm->conn_rule.flow_ident_xlate;
+	nie->return_ip = nircm->tuple.return_ip;
+	nie->return_ip_xlate = nircm->conn_rule.return_ip_xlate;
+	nie->return_ident = nircm->tuple.return_ident;
+	nie->return_ident_xlate = nircm->conn_rule.return_ident_xlate;
+
+	/*
+	 * Call IPv4 manager callback function
+	 */
+	if (!nss_tx_rx_ipv4_event_callback) {
+		nss_info("%p: IPV4 create response message received before connection manager has registered", nss_ctx);
+		return;
+	}
+	cb = nss_tx_rx_ipv4_event_callback;
+	cb(&nicp);
+}
+
+/*
  * nss_tx_create_ipv4_rule()
  *	Create a nss entry to accelerate the given connection
  */
diff --git a/nss_tx_rx_ipv6.c b/nss_tx_rx_ipv6.c
index 10a9ec2..7c864bb 100644
--- a/nss_tx_rx_ipv6.c
+++ b/nss_tx_rx_ipv6.c
@@ -140,6 +140,49 @@
 }
 
 /*
+ * nss_rx_metadata_ipv6_create_response()
+ *	Handle the ACK/NACK responses for IPv6 create rule.
+ */
+void nss_rx_metadata_ipv6_create_response(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
+{
+	struct nss_ipv6_cb_params nicp;
+	nss_ipv6_callback_t cb;
+	struct nss_ipv6_rule_create_msg *nircm;
+	struct nss_ipv6_establish *nie;
+
+	if (nim->cm.response == NSS_CMN_RESPONSE_ACK) {
+		return;
+	}
+
+	nicp.reason = NSS_IPV6_CB_REASON_ESTABLISH_FAIL;
+
+	nircm = &nim->msg.rule_create;
+	nie = &nicp.params.establish;
+
+	nie->protocol = nircm->tuple.protocol;
+	nie->flow_ip[0] = nircm->tuple.flow_ip[0];
+	nie->flow_ip[1] = nircm->tuple.flow_ip[1];
+	nie->flow_ip[2] = nircm->tuple.flow_ip[2];
+	nie->flow_ip[3] = nircm->tuple.flow_ip[3];
+	nie->flow_ident = nircm->tuple.flow_ident;
+	nie->return_ip[0] = nircm->tuple.return_ip[0];
+	nie->return_ip[1] = nircm->tuple.return_ip[1];
+	nie->return_ip[2] = nircm->tuple.return_ip[2];
+	nie->return_ip[3] = nircm->tuple.return_ip[3];
+	nie->return_ident = nircm->tuple.return_ident;
+
+	/*
+	 * Call IPv4 manager callback function
+	 */
+	if (!nss_tx_rx_ipv6_event_callback) {
+		nss_info("%p: IPV6 create response message received before connection manager has registered", nss_ctx);
+		return;
+	}
+	cb = nss_tx_rx_ipv6_event_callback;
+	cb(&nicp);
+}
+
+/*
  * nss_tx_create_ipv6_rule()
  *	Create a NSS entry to accelerate the given connection
  */