Merge "[qca-nss-ecm] Fix route change event handlers."
diff --git a/ecm_db/ecm_db_iface.c b/ecm_db/ecm_db_iface.c
index f529dec..9a465c0 100644
--- a/ecm_db/ecm_db_iface.c
+++ b/ecm_db/ecm_db_iface.c
@@ -1836,7 +1836,7 @@
  * ecm_db_iface_find_and_ref_gre()
  * 	Lookup and return a iface reference if any
  */
-struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_gre_tun(int if_index)
+struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_gre_tun(int if_index, int32_t ae_interface_num)
 {
 	ecm_db_iface_hash_t hash_index;
 	struct ecm_db_iface_instance *ii;
@@ -1856,7 +1856,8 @@
 
 	while (ii) {
 		if ((ii->type != ECM_DB_IFACE_TYPE_GRE_TUN)
-				|| (ii->type_info.gre_tun.if_index != if_index)) {
+				|| (ii->type_info.gre_tun.if_index != if_index)
+				|| (ii->ae_interface_identifier != ae_interface_num)) {
 			ii = ii->hash_next;
 			continue;
 		}
diff --git a/ecm_db/ecm_db_iface.h b/ecm_db/ecm_db_iface.h
index e796459..ea222b4 100644
--- a/ecm_db/ecm_db_iface.h
+++ b/ecm_db/ecm_db_iface.h
@@ -222,7 +222,7 @@
 #endif
 
 #ifdef ECM_INTERFACE_GRE_TUN_ENABLE
-struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_gre_tun(int if_index);
+struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_gre_tun(int if_index, int32_t ae_interface_num);
 void ecm_db_iface_gre_tun_info_get(struct ecm_db_iface_instance *ii, struct ecm_db_interface_info_gre_tun *gre_tun_info);
 void ecm_db_iface_add_gre_tun(struct ecm_db_iface_instance *ii,
 				struct ecm_db_interface_info_gre_tun *gre_tun_info, char *name,
diff --git a/ecm_interface.c b/ecm_interface.c
index e3adac8..9dfbc5e 100644
--- a/ecm_interface.c
+++ b/ecm_interface.c
@@ -1650,10 +1650,9 @@
 	/*
 	 * Locate the iface
 	 */
-	ii = ecm_db_iface_find_and_ref_gre_tun(type_info->if_index);
+	ii = ecm_db_iface_find_and_ref_gre_tun(type_info->if_index, ae_interface_num);
 	if (ii) {
 		DEBUG_TRACE("%p: iface established\n", ii);
-		ecm_db_iface_update_ae_interface_identifier(ii, ae_interface_num);
 		return ii;
 	}
 
@@ -1670,11 +1669,10 @@
 	 * Add iface into the database, atomically to avoid races creating the same thing
 	 */
 	spin_lock_bh(&ecm_interface_lock);
-	ii = ecm_db_iface_find_and_ref_gre_tun(type_info->if_index);
+	ii = ecm_db_iface_find_and_ref_gre_tun(type_info->if_index, ae_interface_num);
 	if (ii) {
 		spin_unlock_bh(&ecm_interface_lock);
 		ecm_db_iface_deref(nii);
-		ecm_db_iface_update_ae_interface_identifier(ii, ae_interface_num);
 		return ii;
 	}
 	ecm_db_iface_add_gre_tun(nii, type_info, dev_name,
@@ -1961,6 +1959,7 @@
 	int32_t dev_mtu;
 	int32_t ae_interface_num;
 	struct ecm_db_iface_instance *ii;
+	int32_t interface_type;
 	union {
 		struct ecm_db_interface_info_ethernet ethernet;		/* type == ECM_DB_IFACE_TYPE_ETHERNET */
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -2122,11 +2121,13 @@
 #endif
 
 #ifdef ECM_INTERFACE_GRE_TAP_ENABLE
-
 		/*
 		 * GRE TAP?
 		 */
 		if (dev->priv_flags & (IFF_GRE_V4_TAP | IFF_GRE_V6_TAP)) {
+			interface_type = feci->ae_interface_type_get(feci, dev);
+			ae_interface_num = feci->ae_interface_number_by_dev_type_get(dev, interface_type);
+
 			/*
 			 * GRE TAP interface is handled as ethernet interface, however it is possible
 			 * that the acceleration engine may not be ready yet to handle the connection.
@@ -2134,7 +2135,7 @@
 			 * we should wait until it is ready.
 			 */
 			if (ae_interface_num < 0) {
-				DEBUG_TRACE("GRE TAP interface is not ready yet\n");
+				DEBUG_TRACE("GRE TAP interface is not ready yet. Interface type: %d\n", interface_type);
 				return NULL;
 			}
 		}
@@ -2209,7 +2210,6 @@
 		struct ip_tunnel *tunnel;
 		struct ip_tunnel_6rd_parm *ip6rd;
 		const struct iphdr  *tiph;
-		int interface_type;
 
 		DEBUG_TRACE("Net device: %p is SIT (6-in-4) type: %d\n", dev, dev_type);
 
@@ -2233,7 +2233,7 @@
 		type_info.sit.ttl = tiph->ttl;
 		type_info.sit.tos = tiph->tos;
 
-		interface_type = feci->ae_interface_type_get(feci, dev_type);
+		interface_type = feci->ae_interface_type_get(feci, dev);
 		ae_interface_num = feci->ae_interface_number_by_dev_type_get(dev, interface_type);
 
 		ii = ecm_interface_sit_interface_establish(&type_info.sit, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
@@ -2250,7 +2250,6 @@
 	if (dev_type == ARPHRD_TUNNEL6) {
 		struct ip6_tnl *tunnel;
 		struct flowi6 *fl6;
-		int interface_type;
 
 		DEBUG_TRACE("Net device: %p is TUNIPIP6 type: %d\n", dev, dev_type);
 
@@ -2266,7 +2265,7 @@
 		type_info.tunipip6.flags = ntohl(tunnel->parms.flags);
 		type_info.tunipip6.flowlabel = fl6->flowlabel;  /* flow Label In kernel is stored in big endian format */
 
-		interface_type = feci->ae_interface_type_get(feci, dev_type);
+		interface_type = feci->ae_interface_type_get(feci, dev);
 		ae_interface_num = feci->ae_interface_number_by_dev_type_get(dev, interface_type);
 
 		if (ae_interface_num < 0) {
@@ -2283,11 +2282,6 @@
 
 #ifdef ECM_INTERFACE_GRE_TUN_ENABLE
 	if ((dev_type == ARPHRD_IPGRE) || (dev_type == ARPHRD_IP6GRE)) {
-		if (ae_interface_num < 0) {
-			DEBUG_TRACE("GRE TUN interface is not ready yet\n");
-			return NULL;
-		}
-
 		type_info.gre_tun.if_index = dev_interface_num;
 		if (dev_type == ARPHRD_IPGRE) {
 			gre4_tunnel = netdev_priv(dev);
@@ -2307,6 +2301,13 @@
 			ECM_NIN6_ADDR_TO_IP_ADDR(type_info.gre_tun.remote_ip, gre6_tunnel->parms.raddr);
 		}
 
+		interface_type = feci->ae_interface_type_get(feci, dev);
+		ae_interface_num = feci->ae_interface_number_by_dev_type_get(dev, interface_type);
+		if (ae_interface_num < 0) {
+			DEBUG_TRACE("GRE TUN interface is not ready yet. Interface type: %d\n", interface_type);
+			return NULL;
+		}
+
 		ii = ecm_interface_gre_tun_interface_establish(&type_info.gre_tun, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
 		if (ii) {
 			/*
diff --git a/frontends/include/ecm_front_end_types.h b/frontends/include/ecm_front_end_types.h
index c13ff9f..0454ccd 100644
--- a/frontends/include/ecm_front_end_types.h
+++ b/frontends/include/ecm_front_end_types.h
@@ -96,7 +96,7 @@
 #endif
 typedef int32_t (*ecm_front_end_connection_ae_interface_number_by_dev_get_method_t)(struct net_device *dev);
 typedef int32_t (*ecm_front_end_connection_ae_interface_number_by_dev_type_get_method_t)(struct net_device *dev, uint32_t type);
-typedef int32_t (*ecm_front_end_connection_ae_interface_type_get_method_t)(struct ecm_front_end_connection_instance *feci, int32_t dev_type);
+typedef int32_t (*ecm_front_end_connection_ae_interface_type_get_method_t)(struct ecm_front_end_connection_instance *feci, struct net_device *dev);
 typedef void (*ecm_front_end_connection_regenerate_method_t)(struct ecm_front_end_connection_instance *feci, struct ecm_db_connection_instance *ci);
 
 /*
@@ -224,7 +224,7 @@
 	bool nss_supported = of_machine_is_compatible("qcom,ipq8064") ||
 				of_machine_is_compatible("qcom,ipq8062") ||
 				of_machine_is_compatible("qcom,ipq807x") ||
-				of_machine_is_compatible("qcom,ipq60xx");
+				of_machine_is_compatible("qcom,ipq6018");
 #else
 	bool nss_supported = true;
 #endif
diff --git a/frontends/nss/ecm_nss_common.h b/frontends/nss/ecm_nss_common.h
index f41229e..722db4a 100644
--- a/frontends/nss/ecm_nss_common.h
+++ b/frontends/nss/ecm_nss_common.h
@@ -100,9 +100,9 @@
  * TODO: For now the feature is the IP version and the net device type. It can be changed
  * in the future for other needs.
  */
-static inline int32_t ecm_nss_common_get_interface_type(struct ecm_front_end_connection_instance *feci, int32_t dev_type)
+static inline int32_t ecm_nss_common_get_interface_type(struct ecm_front_end_connection_instance *feci, struct net_device *dev)
 {
-	switch (dev_type) {
+	switch (dev->type) {
 	case ARPHRD_SIT:
 		if (feci->ip_version == 4) {
 			return NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD_OUTER;
@@ -111,6 +111,7 @@
 		if (feci->ip_version == 6) {
 			return NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD_INNER;
 		}
+		break;
 
 #ifdef ECM_INTERFACE_TUNIPIP6_ENABLE
 	case ARPHRD_TUNNEL6:
@@ -122,7 +123,28 @@
 			return NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER;
 		}
 #endif
+		break;
 
+#ifdef ECM_INTERFACE_GRE_TAP_ENABLE
+	case ARPHRD_ETHER:
+		/*
+		 * If device is not GRETAP then return NONE.
+		 */
+		if (!(dev->priv_flags & (IFF_GRE_V4_TAP | IFF_GRE_V6_TAP))) {
+			break;
+		}
+#endif
+#ifdef ECM_INTERFACE_GRE_TUN_ENABLE
+	case ARPHRD_IPGRE:
+	case ARPHRD_IP6GRE:
+#endif
+#if defined(ECM_INTERFACE_GRE_TAP_ENABLE) || defined(ECM_INTERFACE_GRE_TUN_ENABLE)
+		if (feci->protocol == IPPROTO_GRE) {
+			return NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER;
+		}
+
+		return NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER;
+#endif
 	default:
 		break;
 	}