[qca-nss-ecm] l2tpv2 acceleration support

code enhancements to support l2tpv2 packet acceleration in ecm.

Change-Id: I9c5d55c64fbe0dc0b7b5585801e9da3d28531e31
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
diff --git a/Makefile b/Makefile
index 1dd605d..300fe70 100755
--- a/Makefile
+++ b/Makefile
@@ -68,10 +68,31 @@
 ccflags-$(ECM_INTERFACE_BOND_ENABLE) += -DECM_INTERFACE_BOND_ENABLE
 
 # #############################################################################
-# Define ECM_INTERFACE_PPP_ENABLE=y in order
-# to enable support for PPP and, specifically, PPPoE acceleration.
+# Define ECM_INTERFACE_PPPOE_ENABLE=y in order
+# to enable support for PPPoE acceleration.
+# #############################################################################
+ECM_INTERFACE_PPPOE_ENABLE=y
+ccflags-$(ECM_INTERFACE_PPPOE_ENABLE) += -DECM_INTERFACE_PPPOE_ENABLE
+
+# #############################################################################
+# Define ECM_INTERFACE_L2TPV2_ENABLE=y in order
+# to enable support for l2tpv2 acceleration.
+# #############################################################################
+ifneq ($(findstring 3.4, $(KERNELVERSION)),)
+ECM_INTERFACE_L2TPV2_ENABLE=y
+endif
+ccflags-$(ECM_INTERFACE_L2TPV2_ENABLE) += -DECM_INTERFACE_L2TPV2_ENABLE
+
+# #############################################################################
+# if pppoe, l2tpv2 acceleration is enabled, ppp should
+# be enabled automatically
 # #############################################################################
 ECM_INTERFACE_PPP_ENABLE=y
+ifeq "$(ECM_INTERFACE_PPPOE_ENABLE)" "n"
+ifeq "$(ECM_INTERFACE_L2TPV2_ENABLE)" "n"
+ECM_INTERFACE_PPP_ENABLE=n
+endif
+endif
 ccflags-$(ECM_INTERFACE_PPP_ENABLE) += -DECM_INTERFACE_PPP_ENABLE
 
 # #############################################################################
diff --git a/ecm_db.c b/ecm_db.c
index b7604e2..cd7d254 100644
--- a/ecm_db.c
+++ b/ecm_db.c
@@ -162,7 +162,6 @@
 static int ecm_db_iface_count = 0;			/* Number of interfaces allocated */
 typedef uint32_t ecm_db_iface_hash_t;
 
-
 #define ECM_DB_IFACE_ID_HASH_SLOTS 8
 static struct ecm_db_iface_instance *ecm_db_iface_id_table[ECM_DB_IFACE_ID_HASH_SLOTS];
 							/* Slots of the interface id hash table */
@@ -251,9 +250,12 @@
 		struct ecm_db_interface_info_lag lag;			/* type == ECM_DB_IFACE_TYPE_LAG */
 #endif
 		struct ecm_db_interface_info_bridge bridge;		/* type == ECM_DB_IFACE_TYPE_BRIDGE */
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 		struct ecm_db_interface_info_pppoe pppoe;		/* type == ECM_DB_IFACE_TYPE_PPPOE */
 #endif
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+		struct ecm_db_interface_info_pppol2tpv2 pppol2tpv2;	/* type == ECM_DB_IFACE_TYPE_PPPOL2TPV2 */
+#endif
 		struct ecm_db_interface_info_unknown unknown;		/* type == ECM_DB_IFACE_TYPE_UNKNOWN */
 		struct ecm_db_interface_info_loopback loopback;		/* type == ECM_DB_IFACE_TYPE_LOOPBACK */
 #ifdef ECM_INTERFACE_IPSEC_ENABLE
@@ -880,6 +882,7 @@
 	"UNKNOWN",
 	"SIT",
 	"TUNIPIP6",
+	"PPPoL2TPV2"
 };
 
 /*
@@ -3928,7 +3931,7 @@
 	return (ecm_db_iface_hash_t)(hash_val & (ECM_DB_IFACE_HASH_SLOTS - 1));
 }
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 /*
  * ecm_db_iface_generate_hash_index_pppoe()
  * 	Calculate the hash index.
@@ -3941,6 +3944,20 @@
 }
 #endif
 
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+/*
+ * ecm_db_iface_generate_hash_index_pppol2tpv2()
+ *	Calculate the hash index.
+ */
+static inline ecm_db_iface_hash_t ecm_db_iface_generate_hash_index_pppol2tpv2(uint32_t pppol2tpv2_tunnel_id, uint32_t pppol2tpv2_session_id)
+{
+	uint32_t hash_val;
+	hash_val = (uint32_t)jhash_2words(pppol2tpv2_tunnel_id, pppol2tpv2_session_id, ecm_db_jhash_rnd);
+	return (ecm_db_iface_hash_t)(hash_val & (ECM_DB_IFACE_HASH_SLOTS - 1));
+}
+
+#endif
+
 /*
  * ecm_db_iface_generate_hash_index_unknown()
  * 	Calculate the hash index.
@@ -4395,7 +4412,7 @@
 EXPORT_SYMBOL(ecm_db_iface_find_and_ref_lag);
 #endif
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 /*
  * ecm_db_iface_pppoe_session_info_get()
  *	Get pppoe interface specific information
@@ -4409,6 +4426,7 @@
 	pppoe_info->pppoe_session_id = ii->type_info.pppoe.pppoe_session_id;
 	spin_unlock_bh(&ecm_db_lock);
 }
+
 EXPORT_SYMBOL(ecm_db_iface_pppoe_session_info_get);
 
 /*
@@ -4452,6 +4470,67 @@
 EXPORT_SYMBOL(ecm_db_iface_find_and_ref_pppoe);
 #endif
 
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+
+/*
+ * ecm_db_iface_pppol2tpv2_session_info_get
+ *	get l2tpv2 specific info
+ */
+void ecm_db_iface_pppol2tpv2_session_info_get(struct ecm_db_iface_instance *ii, struct ecm_db_interface_info_pppol2tpv2 *pppol2tpv2_info)
+{
+	DEBUG_CHECK_MAGIC(ii, ECM_DB_IFACE_INSTANCE_MAGIC, "%p: magic failed", ii);
+	DEBUG_ASSERT(ii->type == ECM_DB_IFACE_TYPE_PPPOL2TPV2, "%p: Bad type, expected pppol2tpv2, actual: %d\n", ii, ii->type);
+	spin_lock_bh(&ecm_db_lock);
+	memcpy(pppol2tpv2_info, &ii->type_info.pppol2tpv2, sizeof(struct ecm_db_interface_info_pppol2tpv2));
+	spin_unlock_bh(&ecm_db_lock);
+}
+EXPORT_SYMBOL(ecm_db_iface_pppol2tpv2_session_info_get);
+
+/*
+ * ecm_db_iface_find_and_ref_pppol2tpv2()
+ *	Lookup and return a iface reference if any
+ */
+struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_pppol2tpv2(uint32_t pppol2tpv2_tunnel_id, uint32_t pppol2tpv2_session_id)
+{
+	ecm_db_iface_hash_t hash_index;
+	struct ecm_db_iface_instance *ii;
+
+	/*
+	 * Compute the hash chain index and prepare to walk the chain
+	 */
+	hash_index = ecm_db_iface_generate_hash_index_pppol2tpv2(pppol2tpv2_tunnel_id, pppol2tpv2_session_id);
+
+	DEBUG_TRACE("Lookup pppol2tpv2 iface with local_tunnel_id = %d, local_session_id = %d, hash = 0x%x\n", pppol2tpv2_tunnel_id,
+									pppol2tpv2_session_id, hash_index);
+
+	/*
+	 * Iterate the chain looking for a host with matching details
+	 */
+	spin_lock_bh(&ecm_db_lock);
+	ii = ecm_db_iface_table[hash_index];
+
+	while (ii) {
+		if ((ii->type != ECM_DB_IFACE_TYPE_PPPOL2TPV2)
+				|| (ii->type_info.pppol2tpv2.l2tp.session.session_id != pppol2tpv2_session_id)
+				|| (ii->type_info.pppol2tpv2.l2tp.tunnel.tunnel_id != pppol2tpv2_tunnel_id)) {
+			ii = ii->hash_next;
+			continue;
+		}
+
+		_ecm_db_iface_ref(ii);
+		spin_unlock_bh(&ecm_db_lock);
+		DEBUG_TRACE("iface found %p\n", ii);
+		return ii;
+	}
+	spin_unlock_bh(&ecm_db_lock);
+
+	DEBUG_TRACE("Iface not found\n");
+	return NULL;
+}
+EXPORT_SYMBOL(ecm_db_iface_find_and_ref_pppol2tpv2);
+
+#endif
+
 /*
  * ecm_db_iface_find_and_ref_unknown()
  *	Lookup and return a iface reference if any
@@ -7636,7 +7715,7 @@
 }
 #endif
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 /*
  * ecm_db_iface_pppoe_state_get()
  * 	Return interface type specific state
@@ -7671,6 +7750,51 @@
 }
 #endif
 
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+
+/*
+ * ecm_db_iface_pppol2tpv2_state_get()
+ *	Return interface type specific state
+ */
+static int ecm_db_iface_pppol2tpv2_state_get(struct ecm_db_iface_instance *ii, struct ecm_state_file_instance *sfi)
+{
+	int result;
+	struct ecm_db_interface_info_pppol2tpv2 type_info;
+
+	DEBUG_CHECK_MAGIC(ii, ECM_DB_IFACE_INSTANCE_MAGIC, "%p: magic failed\n", ii);
+	spin_lock_bh(&ecm_db_lock);
+	memcpy(&type_info, &ii->type_info, sizeof(struct ecm_db_interface_info_pppol2tpv2));
+	spin_unlock_bh(&ecm_db_lock);
+
+	if ((result = ecm_state_prefix_add(sfi, "pppol2tpv2"))) {
+		return result;
+	}
+
+	if ((result = ecm_db_iface_state_get_base(ii, sfi))) {
+		return result;
+	}
+
+	if ((result = ecm_state_write(sfi, "local_tunnel_id", "%u", type_info.l2tp.tunnel.tunnel_id))) {
+		return result;
+	}
+
+	if ((result = ecm_state_write(sfi, "local_session_id", "%u", type_info.l2tp.session.session_id))) {
+		return result;
+	}
+
+	if ((result = ecm_state_write(sfi, "peer_tunnnel_id", "%u", type_info.l2tp.tunnel.peer_tunnel_id))) {
+		return result;
+	}
+
+	if ((result = ecm_state_write(sfi, "peer_session_id", "%u", type_info.l2tp.session.peer_session_id))) {
+		return result;
+	}
+
+	return ecm_state_prefix_remove(sfi);
+}
+
+#endif
+
 /*
  * ecm_db_iface_unknown_state_get()
  * 	Return interface type specific state
@@ -9272,7 +9396,7 @@
 EXPORT_SYMBOL(ecm_db_iface_add_vlan);
 #endif
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 /*
  * ecm_db_iface_add_pppoe()
  *	Add a iface instance into the database
@@ -9390,6 +9514,124 @@
 EXPORT_SYMBOL(ecm_db_iface_add_pppoe);
 #endif
 
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+/*
+ * ecm_db_iface_add_pppol2tpv2()
+ *	Add a iface instance into the database
+ */
+void ecm_db_iface_add_pppol2tpv2(struct ecm_db_iface_instance *ii, struct ecm_db_interface_info_pppol2tpv2 *pppol2tpv2_info,
+					char *name, int32_t mtu, int32_t interface_identifier,
+					int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final,
+					void *arg)
+{
+	ecm_db_iface_hash_t hash_index;
+	ecm_db_iface_id_hash_t iface_id_hash_index;
+	struct ecm_db_listener_instance *li;
+	struct ecm_db_interface_info_pppol2tpv2 *type_info;
+
+	spin_lock_bh(&ecm_db_lock);
+	DEBUG_CHECK_MAGIC(ii, ECM_DB_IFACE_INSTANCE_MAGIC, "%p: magic failed\n", ii);
+#ifdef ECM_DB_XREF_ENABLE
+	DEBUG_ASSERT((ii->nodes == NULL) && (ii->node_count == 0), "%p: nodes not null\n", ii);
+#endif
+	DEBUG_ASSERT(!(ii->flags & ECM_DB_IFACE_FLAGS_INSERTED), "%p: inserted\n", ii);
+	DEBUG_ASSERT(name, "%p: no name given\n", ii);
+	spin_unlock_bh(&ecm_db_lock);
+
+	/*
+	 * Record general info
+	 */
+	ii->type = ECM_DB_IFACE_TYPE_PPPOL2TPV2;
+#ifdef ECM_STATE_OUTPUT_ENABLE
+	ii->state_get = ecm_db_iface_pppol2tpv2_state_get;
+#endif
+	ii->arg = arg;
+	ii->final = final;
+	strlcpy(ii->name, name, IFNAMSIZ);
+	ii->mtu = mtu;
+	ii->interface_identifier = interface_identifier;
+	ii->ae_interface_identifier = ae_interface_identifier;
+
+	/*
+	 * Type specific info
+	 */
+	type_info = &ii->type_info.pppol2tpv2;
+	memcpy(type_info, pppol2tpv2_info, sizeof(struct ecm_db_interface_info_pppol2tpv2));
+
+	/*
+	 * Compute hash chain for insertion
+	 */
+	hash_index = ecm_db_iface_generate_hash_index_pppol2tpv2(type_info->l2tp.tunnel.tunnel_id,
+							  type_info->l2tp.session.session_id);
+	ii->hash_index = hash_index;
+
+	iface_id_hash_index = ecm_db_iface_id_generate_hash_index(interface_identifier);
+	ii->iface_id_hash_index = iface_id_hash_index;
+	/*
+	 * Add into the global list
+	 */
+	spin_lock_bh(&ecm_db_lock);
+	ii->flags |= ECM_DB_IFACE_FLAGS_INSERTED;
+	ii->prev = NULL;
+	ii->next = ecm_db_interfaces;
+	if (ecm_db_interfaces) {
+		ecm_db_interfaces->prev = ii;
+	}
+	ecm_db_interfaces = ii;
+
+	/*
+	 * Insert into chain
+	 */
+	ii->hash_next = ecm_db_iface_table[hash_index];
+	if (ecm_db_iface_table[hash_index]) {
+		ecm_db_iface_table[hash_index]->hash_prev = ii;
+	}
+	ecm_db_iface_table[hash_index] = ii;
+	ecm_db_iface_table_lengths[hash_index]++;
+	DEBUG_ASSERT(ecm_db_iface_table_lengths[hash_index] > 0, "%p: invalid table len %d\n", ii, ecm_db_iface_table_lengths[hash_index]);
+
+	DEBUG_INFO("%p: interface inserted at hash index %u, hash prev is %p, type: %d\n", ii, ii->hash_index, ii->hash_prev, ii->type);
+
+	/*
+	 * Insert into interface identifier chain
+	 */
+	ii->iface_id_hash_next = ecm_db_iface_id_table[iface_id_hash_index];
+	if (ecm_db_iface_id_table[iface_id_hash_index]) {
+		ecm_db_iface_id_table[iface_id_hash_index]->iface_id_hash_prev = ii;
+	}
+	ecm_db_iface_id_table[iface_id_hash_index] = ii;
+	ecm_db_iface_id_table_lengths[iface_id_hash_index]++;
+	DEBUG_ASSERT(ecm_db_iface_id_table_lengths[iface_id_hash_index] > 0, "%p: invalid iface id table len %d\n", ii, ecm_db_iface_id_table_lengths[iface_id_hash_index]);
+
+	/*
+	 * Set time of addition
+	 */
+	ii->time_added = ecm_db_time;
+	spin_unlock_bh(&ecm_db_lock);
+
+	/*
+	 * Throw add event to the listeners
+	 */
+	DEBUG_TRACE("%p: Throw iface added event\n", ii);
+	li = ecm_db_listeners_get_and_ref_first();
+	while (li) {
+		struct ecm_db_listener_instance *lin;
+		if (li->iface_added) {
+			li->iface_added(li->arg, ii);
+		}
+
+		/*
+		 * Get next listener
+		 */
+		lin = ecm_db_listener_get_and_ref_next(li);
+		ecm_db_listener_deref(li);
+		li = lin;
+	}
+}
+EXPORT_SYMBOL(ecm_db_iface_add_pppol2tpv2);
+
+#endif
+
 /*
  * ecm_db_iface_add_unknown()
  *	Add a iface instance into the database
@@ -10131,7 +10373,6 @@
 }
 EXPORT_SYMBOL(ecm_db_mapping_alloc);
 
-
 /*
  * ecm_db_host_alloc()
  *	Allocate a host instance
diff --git a/ecm_db.h b/ecm_db.h
index 186d4e0..d9e7d70 100644
--- a/ecm_db.h
+++ b/ecm_db.h
@@ -20,7 +20,6 @@
 #ifndef ECM_DB_H_
 #define ECM_DB_H_
 
-
 uint32_t ecm_db_time_get(void);
 void ecm_db_connection_defunct_all(void);
 #ifdef ECM_DB_XREF_ENABLE
@@ -130,7 +129,7 @@
 
 void ecm_db_iface_ethernet_address_get(struct ecm_db_iface_instance *ii, uint8_t *address);
 void ecm_db_iface_bridge_address_get(struct ecm_db_iface_instance *ii, uint8_t *address);
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 void ecm_db_iface_pppoe_session_info_get(struct ecm_db_iface_instance *ii, struct ecm_db_interface_info_pppoe *pppoe_info);
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -147,9 +146,13 @@
 #endif
 struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_bridge(uint8_t *address);
 struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_unknown(uint32_t os_specific_ident);
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_pppoe(uint16_t pppoe_session_id, uint8_t *remote_mac);
 #endif
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+void ecm_db_iface_pppol2tpv2_session_info_get(struct ecm_db_iface_instance *ii, struct ecm_db_interface_info_pppol2tpv2 *pppol2tpv2_info);
+struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_pppol2tpv2(uint32_t pppol2tpv2_tunnel_id, uint32_t pppol2tpv2_session_id);
+#endif
 struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_loopback(uint32_t os_specific_ident);
 #ifdef ECM_INTERFACE_IPSEC_ENABLE
 struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_ipsec_tunnel(uint32_t os_specific_ident);
@@ -266,9 +269,14 @@
 #ifdef ECM_INTERFACE_VLAN_ENABLE
 void ecm_db_iface_add_vlan(struct ecm_db_iface_instance *ii, uint8_t *address, uint16_t vlan_tag, uint16_t vlan_tpid, char *name, int32_t mtu, int32_t interface_identifier, int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final, void *arg);
 #endif
-#ifdef ECM_INTERFACE_PPP_ENABLE
+
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 void ecm_db_iface_add_pppoe(struct ecm_db_iface_instance *ii, uint16_t pppoe_session_id, uint8_t *remote_mac, char *name, int32_t mtu, int32_t interface_identifier, int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final, void *arg);
 #endif
+
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+void ecm_db_iface_add_pppol2tpv2(struct ecm_db_iface_instance *ii, struct ecm_db_interface_info_pppol2tpv2 *pppol2tpv2_info, char *name, int32_t mtu, int32_t interface_identifier, int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final, void *arg);
+#endif
 void ecm_db_iface_add_unknown(struct ecm_db_iface_instance *ii, uint32_t os_specific_ident, char *name, int32_t mtu, int32_t interface_identifier, int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final, void *arg);
 void ecm_db_iface_add_loopback(struct ecm_db_iface_instance *ii, uint32_t os_specific_ident, char *name, int32_t mtu, int32_t interface_identifier, int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final, void *arg);
 #ifdef ECM_INTERFACE_IPSEC_ENABLE
diff --git a/ecm_db_types.h b/ecm_db_types.h
index 9cacee6..69e526d 100644
--- a/ecm_db_types.h
+++ b/ecm_db_types.h
@@ -81,7 +81,6 @@
 typedef void (*ecm_db_iface_listener_added_callback_t)(void *arg, struct ecm_db_iface_instance *ii);		/* Added callback */
 typedef void (*ecm_db_iface_listener_removed_callback_t)(void *arg, struct ecm_db_iface_instance *ii);		/* Removed callback */
 
-
 /*
  * Time out values - in seconds - used to configure timer groups
  */
@@ -242,6 +241,7 @@
 	ECM_DB_IFACE_TYPE_UNKNOWN,			/* Interface is unknown to the ECM */
 	ECM_DB_IFACE_TYPE_SIT,				/* IPv6 in IPv4 tunnel (SIT) interface */
 	ECM_DB_IFACE_TYPE_TUNIPIP6,			/* IPIP6 Tunnel (TUNNEL6) interface */
+	ECM_DB_IFACE_TYPE_PPPOL2TPV2,			/* Interface is a PPPoL2TPV2 interface (a specific form of PPP that we recognise in the ECM) */
 	ECM_DB_IFACE_TYPE_COUNT,			/* Number of interface types */
 };
 typedef enum ecm_db_iface_types ecm_db_iface_type_t;
@@ -271,12 +271,35 @@
 	uint8_t address[ETH_ALEN];			/* MAC Address of this Interface */
 };
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 struct ecm_db_interface_info_pppoe {			/* type == ECM_DB_IFACE_TYPE_PPPOE */
-       	uint16_t pppoe_session_id;			/* PPPoE session ID on this interface, when applicable */
+	uint16_t pppoe_session_id;			/* PPPoE session ID on this interface, when applicable */
 	uint8_t remote_mac[ETH_ALEN];			/* MAC Address of the PPPoE concentrator */
 };
 #endif
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+struct ecm_db_interface_info_pppol2tpv2 {                  /* type == ECM_DB_IFACE_TYPE_PPPOL2TPV2 */
+	struct {
+		struct {
+			uint32_t tunnel_id;
+			uint32_t peer_tunnel_id;
+		} tunnel;
+		struct {
+			uint32_t session_id;
+			uint32_t peer_session_id;
+		} session;
+	} l2tp;
+
+	struct {
+		uint16_t sport, dport;
+	} udp;
+
+	struct {
+		uint32_t  saddr, daddr;
+	} ip;
+};
+
+#endif
 
 struct ecm_db_interface_info_unknown {			/* type == ECM_DB_IFACE_TYPE_UNKNOWN */
 	uint32_t os_specific_ident;			/* Operating system specific identifier (known only by front end) */
@@ -328,7 +351,7 @@
  * Therefore the first interface in the list is the outermost interface, which is for acceleration, hopefully an accel engine supported interface.
  * Lists have a finite size.
  */
-#define ECM_DB_IFACE_HEIRARCHY_MAX 10		/* This is the number of interfaces allowed in a heirarchy */
+#define ECM_DB_IFACE_HEIRARCHY_MAX 9 /* This is the number of interfaces allowed in a heirarchy */
 
 #ifdef ECM_MULTICAST_ENABLE
 /*
diff --git a/ecm_interface.c b/ecm_interface.c
index 5bd392e..9df4963 100644
--- a/ecm_interface.c
+++ b/ecm_interface.c
@@ -71,6 +71,10 @@
 #endif
 #ifdef ECM_INTERFACE_PPP_ENABLE
 #include <linux/if_pppox.h>
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+#include <linux/l2tp.h>
+#include <linux/../../net/l2tp/l2tp_core.h>
+#endif
 #endif
 
 /*
@@ -754,6 +758,183 @@
 #endif
 
 #ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+/*
+ * ecm_interface_skip_l2tpv3_pptp()
+ *	skip pptp tunnel encapsulated traffic
+ *
+ * ECM does not handle  PPTP and l2tpv3,
+ * this function detects packets of that type so they can be skipped over to improve their throughput.
+ */
+bool ecm_interface_skip_l2tpv3_pptp(struct sk_buff *skb, const struct net_device *out)
+{
+	struct ppp_channel *ppp_chan[1];
+	int px_proto;
+	struct net_device *in;
+	bool ret = true;
+	struct sock *sk = NULL;
+	struct l2tp_session *session = NULL;
+	struct l2tp_tunnel *tunnel = NULL;
+	struct ppp_channel *pch = NULL;
+
+	/*
+	 * skip first pass of l2tpv3/pptp tunnel encapsulated traffic
+	 */
+	if (out->type == ARPHRD_PPP) {
+		if (ppp_hold_channels((struct net_device *)out, ppp_chan, 1) != 1) {
+			return true;
+		}
+
+		px_proto = ppp_channel_get_protocol(ppp_chan[0]);
+
+		/*
+		 * Skip packets for PPPoPPTP channel
+		 */
+		if (px_proto == PX_PROTO_PPTP) {
+			ppp_release_channels(ppp_chan, 1);
+			return true;
+		}
+
+		/*
+		 * Check for PPPoL2TP channel
+		 */
+		if (px_proto == PX_PROTO_OL2TP) {
+			pch = ppp_chan[0];
+			sk = pch->private;
+			sock_hold(sk);
+
+			/*
+			 * Get L2TP session for this PPP channel
+			 */
+			session = (struct l2tp_session *)(sk->sk_user_data);
+			if ((session == NULL) || (session->magic != L2TP_SESSION_MAGIC)) {
+				sock_put(sk);
+				ppp_release_channels(ppp_chan, 1);
+				return true;
+			}
+
+			tunnel = session->tunnel;
+
+			/*
+			 * Check L2TP tunnel version
+			 */
+			if (tunnel->version == 2) {
+				ret = false;
+			} else {
+				ret = true;
+			}
+
+			sock_put(sk);
+			ppp_release_channels(ppp_chan, 1);
+			return ret;
+		}
+
+		ppp_release_channels(ppp_chan, 1);
+		return false;
+	}
+
+	in = dev_get_by_index(&init_net, skb->skb_iif);
+	if (in && in->type == ARPHRD_PPP) {
+		/*
+		 * Skip L2TPv3 IP encapsulated packets
+		 */
+		if ((skb->sk) && (skb->sk->sk_protocol == IPPROTO_L2TP)) {
+			dev_put(in);
+			return true;
+		}
+
+		/*
+		 * Chack for L2TP UDP encapsulated packets
+		 */
+		if ((skb->sk) && (skb->sk->sk_protocol == IPPROTO_UDP)
+		    && (udp_sk(skb->sk)->encap_type == UDP_ENCAP_L2TPINUDP)) {
+			/*
+			 * Get the L2TP tunnel socket this packet is associated with
+			 */
+			sk = skb->sk;
+			tunnel = l2tp_sock_to_tunnel(sk);
+			if (tunnel == NULL) {
+				dev_put(in);
+				return false;
+			}
+
+			if (tunnel->version == 2) {
+				ret = false;
+			} else {
+				ret = true;
+			}
+
+			dev_put(in);
+			sock_put(sk);
+			return ret;
+		}
+
+		/*
+		 * Packet is not associated with a L2TP tunnel socket.
+		 * Check 'in' netdevice for type of PPPoX channel.
+		 */
+		if (ppp_hold_channels((struct net_device *)in, ppp_chan, 1) != 1) {
+			dev_put(in);
+			return true;
+		}
+
+		dev_put(in);
+		px_proto = ppp_channel_get_protocol(ppp_chan[0]);
+
+		/*
+		 * Skip packets for PPPoPPTP channel
+		 */
+		if (px_proto == PX_PROTO_PPTP) {
+			ppp_release_channels(ppp_chan, 1);
+			return true;
+		}
+
+		/*
+		 * Check for PPPoL2TP channel
+		 */
+		if (px_proto == PX_PROTO_OL2TP) {
+			pch = ppp_chan[0];
+			sk = pch->private;
+			sock_hold(sk);
+
+			/*
+			 * Get L2TP session for this PPP channel
+			 */
+			session = (struct l2tp_session *)(sk->sk_user_data);
+			if ((session == NULL) || (session->magic != L2TP_SESSION_MAGIC)) {
+				sock_put(sk);
+				ppp_release_channels(ppp_chan, 1);
+				return true;
+			}
+
+			tunnel = session->tunnel;
+
+			/*
+			 * Check L2TP tunnel version
+			 */
+			if (tunnel->version == 2) {
+				ret = false;
+			} else {
+				ret = true;
+			}
+
+			sock_put(sk);
+			ppp_release_channels(ppp_chan, 1);
+			return ret;
+		}
+
+		ppp_release_channels(ppp_chan, 1);
+		return false;
+	}
+
+	if (in) {
+		dev_put(in);
+	}
+
+	return false;
+}
+#endif
+
 /*
  * ecm_interface_skip_l2tp_pptp()
  *	skip l2tp/pptp tunnel encapsulated traffic
@@ -1001,7 +1182,7 @@
 	return nii;
 }
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 /*
  * ecm_interface_pppoe_interface_establish()
  *	Returns a reference to a iface of the PPPoE type, possibly creating one if necessary.
@@ -1053,6 +1234,58 @@
 }
 #endif
 
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+/*
+ * ecm_interface_pppol2tpv2_interface_establish()
+ *	Returns a reference to a iface of the PPPoL2TPV2 type, possibly creating one if necessary.
+ *	Returns NULL on failure or a reference to interface.
+ */
+static struct ecm_db_iface_instance *ecm_interface_pppol2tpv2_interface_establish(struct ecm_db_interface_info_pppol2tpv2 *type_info,
+							char *dev_name, int32_t dev_interface_num, int32_t ae_interface_num, int32_t mtu)
+{
+	struct ecm_db_iface_instance *nii;
+	struct ecm_db_iface_instance *ii;
+
+	DEBUG_INFO("Establish PPPol2tp iface: %s with tunnel id=%u session id %u\n", dev_name, type_info->l2tp.tunnel.tunnel_id,
+				type_info->l2tp.session.session_id);
+	/*
+	 * Locate the iface
+	 */
+	ii = ecm_db_iface_find_and_ref_pppol2tpv2(type_info->l2tp.tunnel.tunnel_id, type_info->l2tp.session.session_id);
+	if (ii) {
+		DEBUG_TRACE("%p: iface established\n", ii);
+		return ii;
+	}
+
+	/*
+	 * No iface - create one
+	 */
+	nii = ecm_db_iface_alloc();
+	if (!nii) {
+		DEBUG_WARN("Failed to establish iface\n");
+		return NULL;
+	}
+
+	/*
+	 * 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_pppol2tpv2(type_info->l2tp.tunnel.tunnel_id, type_info->l2tp.session.session_id);
+	if (ii) {
+		spin_unlock_bh(&ecm_interface_lock);
+		ecm_db_iface_deref(nii);
+		return ii;
+	}
+
+	ecm_db_iface_add_pppol2tpv2(nii, type_info, dev_name, mtu, dev_interface_num, ae_interface_num, NULL, nii);
+	spin_unlock_bh(&ecm_interface_lock);
+
+	DEBUG_TRACE("%p: pppol2tpv2 iface established\n", nii);
+	return nii;
+}
+
+#endif
+
 /*
  * ecm_interface_unknown_interface_establish()
  *	Returns a reference to a iface of the UNKNOWN type, possibly creating one if necessary.
@@ -1320,7 +1553,7 @@
  *	Establish an interface instance for the given interface detail.
  */
 struct ecm_db_iface_instance *ecm_interface_establish_and_ref(struct ecm_front_end_connection_instance *feci,
-								struct net_device *dev)
+								struct net_device *dev, struct sk_buff *skb)
 {
 	int32_t dev_interface_num;
 	char *dev_name;
@@ -1337,9 +1570,12 @@
 		struct ecm_db_interface_info_lag lag;			/* type == ECM_DB_IFACE_TYPE_LAG */
 #endif
 		struct ecm_db_interface_info_bridge bridge;		/* type == ECM_DB_IFACE_TYPE_BRIDGE */
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 		struct ecm_db_interface_info_pppoe pppoe;		/* type == ECM_DB_IFACE_TYPE_PPPOE */
 #endif
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+		struct ecm_db_interface_info_pppol2tpv2 pppol2tpv2;		/* type == ECM_DB_IFACE_TYPE_PPPOL2TPV2 */
+#endif
 		struct ecm_db_interface_info_unknown unknown;		/* type == ECM_DB_IFACE_TYPE_UNKNOWN */
 		struct ecm_db_interface_info_loopback loopback;		/* type == ECM_DB_IFACE_TYPE_LOOPBACK */
 #ifdef ECM_INTERFACE_IPSEC_ENABLE
@@ -1359,8 +1595,10 @@
 	int channel_count;
 	struct ppp_channel *ppp_chan[1];
 	int channel_protocol;
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 	struct pppoe_opt addressing;
 #endif
+#endif
 
 	/*
 	 * Get basic information about the given device
@@ -1595,6 +1833,90 @@
 	ii = ecm_interface_unknown_interface_establish(&type_info.unknown, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
 	return ii;
 #else
+
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+	/*
+	 * ppp_xmit lock is held by linux kernel for l2tp packet in transmit
+	 * direction. we need to check for l2tp packet and avoid calls to
+	 * ppp_is_multilink() and ppp_hold_channels() which acquire same lock
+	 */
+	if (skb && skb->sk && (skb->sk->sk_protocol == IPPROTO_UDP)
+	    && (udp_sk(skb->sk)->encap_type == UDP_ENCAP_L2TPINUDP)) {
+		struct sock *sk = NULL;
+		struct inet_sock *inet = NULL;
+		struct l2tp_session *session = NULL;
+		struct l2tp_session *temp_session = NULL;
+		struct l2tp_tunnel *tunnel = NULL;
+		int hash;
+		struct hlist_node *walk = NULL;
+
+		/*
+		 * PPPoL2TPV2 channel
+		 */
+		DEBUG_TRACE("%p:  PPP channel is PPPoL2TPV2 (%s)\n", dev, dev->name);
+
+		/*
+		 * Get the L2TP tunnel socket this packet is associated with
+		 */
+		sk = skb->sk;
+		tunnel = l2tp_sock_to_tunnel(sk);
+		if (tunnel == NULL) {
+			return NULL;
+		}
+
+		/*
+		 * Check L2TPv2 tunnel version
+		 */
+		if (tunnel->version != 2) {
+			sock_put(sk);
+			return NULL;
+		}
+
+		/*
+		 * Find the L2TP session this packet is associated with
+		 */
+		read_lock_bh(&tunnel->hlist_lock);
+		for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
+			hlist_for_each_entry(temp_session, walk,
+					     &tunnel->session_hlist[hash], hlist) {
+				if (!strcmp(temp_session->ifname, dev_name)) {
+					session = temp_session;
+					break;
+				}
+			}
+		}
+		read_unlock_bh(&tunnel->hlist_lock);
+
+		if (session == NULL) {
+			sock_put(sk);
+			return NULL;
+		}
+
+		inet = inet_sk(sk);
+		l2tp_session_inc_refcount(session);
+
+		type_info.pppol2tpv2.l2tp.tunnel.tunnel_id = tunnel->tunnel_id;
+		type_info.pppol2tpv2.l2tp.tunnel.peer_tunnel_id = tunnel->peer_tunnel_id;
+		type_info.pppol2tpv2.l2tp.session.session_id = session->session_id;
+		type_info.pppol2tpv2.l2tp.session.peer_session_id = session->peer_session_id;
+		type_info.pppol2tpv2.udp.sport = ntohs(inet->inet_sport);
+		type_info.pppol2tpv2.udp.dport = ntohs(inet->inet_sport);
+		type_info.pppol2tpv2.ip.saddr = ntohl(inet->inet_saddr);
+		type_info.pppol2tpv2.ip.daddr = ntohl(inet->inet_daddr);
+
+		l2tp_session_dec_refcount(session);
+		sock_put(sk);
+
+		DEBUG_TRACE("%p: found PPPo2L2TP session\n", dev);
+
+		/*
+		 * Establish this type of interface
+		 */
+		ii = ecm_interface_pppol2tpv2_interface_establish(&type_info.pppol2tpv2, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
+		return ii;
+	}
+#endif
+
 	/*
 	 * PPP - but what is the channel type?
 	 * First: If this is multi-link then we do not support it
@@ -1634,48 +1956,122 @@
 	 * NOTE: Not all PPP channels support channel specific methods.
 	 */
 	channel_protocol = ppp_channel_get_protocol(ppp_chan[0]);
-	if (channel_protocol != PX_PROTO_OE) {
-		DEBUG_TRACE("Net device: %p PPP channel protocol: %d - Unknown to the ECM\n", dev, channel_protocol);
-		type_info.unknown.os_specific_ident = dev_interface_num;
+
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+	if (channel_protocol == PX_PROTO_OL2TP) {
+		struct ppp_channel *pch = ppp_chan[0];
+		struct sock *sk = NULL;
+		struct sock *tunsk = NULL;
+		struct l2tp_session *session = NULL;
+		struct l2tp_tunnel *tunnel = NULL;
+		struct inet_sock *inet = NULL;
 
 		/*
-		 * Release the channel
+		 * PPPoL2TPV2 channel
+		 */
+		DEBUG_TRACE("Net device: %p PPP channel is PPPoL2TPV2 %s\n", dev, dev->name);
+
+		sk = pch->private;
+		sock_hold(sk);
+
+		/*
+		 * Get L2TP session
+		 */
+		session = (struct l2tp_session *)(sk->sk_user_data);
+		if ((session == NULL) || (session->magic != L2TP_SESSION_MAGIC)) {
+			sock_put(sk);
+			ppp_release_channels(ppp_chan, 1);
+			return NULL;
+		}
+
+		l2tp_session_inc_refcount(session);
+		sock_put(sk);
+
+		/*
+		 * Get L2TPv2 tunnel
+		 */
+		tunnel = session->tunnel;
+		if (tunnel->version != 2) {
+			l2tp_session_dec_refcount(session);
+			ppp_release_channels(ppp_chan, 1);
+			return NULL;
+		}
+
+		tunsk = tunnel->sock;
+		sock_hold(tunsk);
+		inet = inet_sk(tunsk);
+
+		type_info.pppol2tpv2.l2tp.tunnel.tunnel_id = tunnel->tunnel_id;
+		type_info.pppol2tpv2.l2tp.tunnel.peer_tunnel_id = tunnel->peer_tunnel_id;
+		type_info.pppol2tpv2.l2tp.session.session_id = session->session_id;
+		type_info.pppol2tpv2.l2tp.session.peer_session_id = session->peer_session_id;
+		type_info.pppol2tpv2.udp.sport = ntohs(inet->inet_sport);
+		type_info.pppol2tpv2.udp.dport = ntohs(inet->inet_sport);
+		type_info.pppol2tpv2.ip.saddr = ntohl(inet->inet_saddr);
+		type_info.pppol2tpv2.ip.daddr = ntohl(inet->inet_daddr);
+
+		l2tp_session_dec_refcount(session);
+		sock_put(tunsk);
+
+		/*
+		 * Release the channel.  Note that next_dev is still (correctly) held.
 		 */
 		ppp_release_channels(ppp_chan, 1);
 
+		DEBUG_TRACE("Net device: %p PPPo2L2TP session: %d,n", dev, type_info.pppol2tpv2.l2tp.session.peer_session_id);
+
 		/*
 		 * Establish this type of interface
 		 */
-		ii = ecm_interface_unknown_interface_establish(&type_info.unknown, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
+		ii = ecm_interface_pppol2tpv2_interface_establish(&type_info.pppol2tpv2, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
 		return ii;
 	}
+#endif
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
+	if (channel_protocol == PX_PROTO_OE) {
+
+		/*
+		 * PPPoE channel
+		 */
+		DEBUG_TRACE("Net device: %p PPP channel is PPPoE\n", dev);
+
+		/*
+		 * Get PPPoE session information and the underlying device it is using.
+		 */
+		pppoe_channel_addressing_get(ppp_chan[0], &addressing);
+		type_info.pppoe.pppoe_session_id = (uint16_t)ntohs((uint16_t)addressing.pa.sid);
+		memcpy(type_info.pppoe.remote_mac, addressing.pa.remote, ETH_ALEN);
+		dev_put(addressing.dev);
+
+		/*
+		 * Release the channel.  Note that next_dev is still (correctly) held.
+		 */
+		ppp_release_channels(ppp_chan, 1);
+
+		DEBUG_TRACE("Net device: %p PPPoE session: %x, remote mac: %pM\n",
+			    dev, type_info.pppoe.pppoe_session_id, type_info.pppoe.remote_mac);
+
+		/*
+		 * Establish this type of interface
+		 */
+		ii = ecm_interface_pppoe_interface_establish(&type_info.pppoe, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
+		return ii;
+	}
+#endif
+	DEBUG_TRACE("Net device: %p PPP channel protocol: %d - Unknown to the ECM\n", dev, channel_protocol);
+	type_info.unknown.os_specific_ident = dev_interface_num;
 
 	/*
-	 * PPPoE channel
-	 */
-	DEBUG_TRACE("Net device: %p PPP channel is PPPoE\n", dev);
-
-	/*
-	 * Get PPPoE session information and the underlying device it is using.
-	 */
-	pppoe_channel_addressing_get(ppp_chan[0], &addressing);
-	type_info.pppoe.pppoe_session_id = (uint16_t)ntohs((uint16_t)addressing.pa.sid);
-	memcpy(type_info.pppoe.remote_mac, addressing.pa.remote, ETH_ALEN);
-	dev_put(addressing.dev);
-
-	/*
-	 * Release the channel.  Note that next_dev is still (correctly) held.
+	 * Release the channel
 	 */
 	ppp_release_channels(ppp_chan, 1);
 
-	DEBUG_TRACE("Net device: %p PPPoE session: %x, remote mac: %pM\n",
-			dev, type_info.pppoe.pppoe_session_id, type_info.pppoe.remote_mac);
-
 	/*
 	 * Establish this type of interface
 	 */
-	ii = ecm_interface_pppoe_interface_establish(&type_info.pppoe, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
+	ii = ecm_interface_unknown_interface_establish(&type_info.unknown, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
 	return ii;
+
 #endif
 }
 EXPORT_SYMBOL(ecm_interface_establish_and_ref);
@@ -1691,11 +2087,12 @@
  *	given_dest_dev	Netdev pointer for destination interface
  *	br_slave_dev	Netdev pointer to a bridge slave device. It could be NULL in case of pure
  *			routed flow without any bridge interface in destination dev list.
+ *	skb             sk_buff
  */
 static uint32_t ecm_interface_multicast_heirarchy_construct_single(struct ecm_front_end_connection_instance *feci, ip_addr_t src_addr,
 								   ip_addr_t dest_addr, struct ecm_db_iface_instance *interface,
 								   struct net_device *given_dest_dev, struct net_device *br_slave_dev,
-								   uint8_t *src_node_addr, bool is_routed, __be16 *layer4hdr)
+								   uint8_t *src_node_addr, bool is_routed, __be16 *layer4hdr, struct sk_buff *skb)
 {
 	struct ecm_db_iface_instance *to_list_single[ECM_DB_IFACE_HEIRARCHY_MAX];
 	struct ecm_db_iface_instance **ifaces;
@@ -1717,7 +2114,7 @@
 		/*
 		 * Get the ecm db interface instance for the device at hand
 		 */
-		ii = ecm_interface_establish_and_ref(feci, dest_dev);
+		ii = ecm_interface_establish_and_ref(feci, dest_dev, skb);
 		interfaces_cnt++;
 
 		/*
@@ -1995,7 +2392,6 @@
 			 */
 			next_dev = addressing.dev;
 
-
 			/*
 			 * Release the channel.  Note that next_dev is still (correctly) held.
 			 */
@@ -2058,7 +2454,7 @@
 								ip_addr_t packet_dest_addr, uint8_t max_if,
 								uint32_t *dst_if_index_base,
 								uint32_t *interface_first_base,
-								__be16 *layer4hdr)
+								__be16 *layer4hdr, struct sk_buff *skb)
 {
 	struct ecm_db_iface_instance *to_list_single[ECM_DB_IFACE_HEIRARCHY_MAX];
 	struct ecm_db_iface_instance *ifaces;
@@ -2203,7 +2599,7 @@
 				/*
 				 * Construct a single interface heirarchy of a multicast dev.
 				 */
-				ii_cnt = ecm_interface_multicast_heirarchy_construct_single(feci, packet_src_addr, packet_dest_addr, ifaces, dest_dev, mc_br_slave_dev, NULL, true, layer4hdr);
+				ii_cnt = ecm_interface_multicast_heirarchy_construct_single(feci, packet_src_addr, packet_dest_addr, ifaces, dest_dev, mc_br_slave_dev, NULL, true, layer4hdr, skb);
 				if (ii_cnt == ECM_DB_IFACE_HEIRARCHY_MAX) {
 
 					/*
@@ -2239,7 +2635,7 @@
 			/*
 			 * Construct a single interface heirarchy of a multicast dev.
 			 */
-			ii_cnt = ecm_interface_multicast_heirarchy_construct_single(feci, packet_src_addr, packet_dest_addr, ifaces, dest_dev, NULL, NULL, true, layer4hdr);
+			ii_cnt = ecm_interface_multicast_heirarchy_construct_single(feci, packet_src_addr, packet_dest_addr, ifaces, dest_dev, NULL, NULL, true, layer4hdr, skb);
 			if (ii_cnt == ECM_DB_IFACE_HEIRARCHY_MAX) {
 
 				/*
@@ -2288,7 +2684,7 @@
 						     struct ecm_db_iface_instance *interfaces, struct net_device *dest_dev,
 						     ip_addr_t packet_src_addr, ip_addr_t packet_dest_addr, uint8_t mc_max_dst,
 						     int *mc_dst_if_index_base, uint32_t *interface_first_base, uint8_t *src_node_addr,
-						     __be16 *layer4hdr)
+						     __be16 *layer4hdr, struct sk_buff *skb)
 {
 	struct ecm_db_iface_instance *to_list_single[ECM_DB_IFACE_HEIRARCHY_MAX];
 	struct ecm_db_iface_instance *ifaces;
@@ -2350,7 +2746,7 @@
 		/*
 		 * Construct a single interface heirarchy of a multicast dev.
 		 */
-		ii_cnt = ecm_interface_multicast_heirarchy_construct_single(feci, packet_src_addr, packet_dest_addr, ifaces, dest_dev, mc_br_slave_dev, src_node_addr, false, layer4hdr);
+		ii_cnt = ecm_interface_multicast_heirarchy_construct_single(feci, packet_src_addr, packet_dest_addr, ifaces, dest_dev, mc_br_slave_dev, src_node_addr, false, layer4hdr, skb);
 		if (ii_cnt == ECM_DB_IFACE_HEIRARCHY_MAX) {
 
 			/*
@@ -2415,7 +2811,7 @@
 						struct net_device *given_dest_dev,
 						bool is_routed, struct net_device *given_src_dev,
 						uint8_t *dest_node_addr, uint8_t *src_node_addr,
-						__be16 *layer4hdr)
+						__be16 *layer4hdr, struct sk_buff *skb)
 {
 	int protocol;
 	ip_addr_t src_addr;
@@ -2501,6 +2897,21 @@
 			}
 		}
 	}
+
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+	/*
+	 * if the address is a local address and indev=l2tp.
+	 */
+	if (skb && skb->sk && (skb->sk->sk_protocol == IPPROTO_UDP) && (udp_sk(skb->sk)->encap_type == UDP_ENCAP_L2TPINUDP)) {
+		dev_put(dest_dev);
+		dest_dev = given_dest_dev;
+		if (dest_dev) {
+			dev_hold(dest_dev);
+			DEBUG_TRACE("l2tp packet tunnel packet with dest_addr: " ECM_IP_ADDR_OCTAL_FMT " uses dev: %p(%s)\n", ECM_IP_ADDR_TO_OCTAL(dest_addr), dest_dev, dest_dev->name);
+		}
+	}
+#endif
+
 	if (!dest_dev) {
 		DEBUG_WARN("dest_addr: " ECM_IP_ADDR_OCTAL_FMT " - cannot locate device\n", ECM_IP_ADDR_TO_OCTAL(dest_addr));
 		return ECM_DB_IFACE_HEIRARCHY_MAX;
@@ -2608,7 +3019,7 @@
 		/*
 		 * Get the ecm db interface instance for the device at hand
 		 */
-		ii = ecm_interface_establish_and_ref(feci, dest_dev);
+		ii = ecm_interface_establish_and_ref(feci, dest_dev, skb);
 
 		/*
 		 * If the interface could not be established then we abort
@@ -2640,8 +3051,10 @@
 			int channel_count;
 			struct ppp_channel *ppp_chan[1];
 			int channel_protocol;
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct pppoe_opt addressing;
 #endif
+#endif
 
 			DEBUG_TRACE("Net device: %p is type: %d, name: %s\n", dest_dev, dest_dev_type, dest_dev_name);
 			next_dev = NULL;
@@ -2912,6 +3325,14 @@
 #ifndef ECM_INTERFACE_PPP_ENABLE
 			DEBUG_TRACE("Net device: %p is UNKNOWN (PPP Unsupported) type: %d\n", dest_dev, dest_dev_type);
 #else
+			DEBUG_TRACE("Net device: %p is PPP\n", dest_dev);
+
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+			if (skb && skb->sk && (skb->sk->sk_protocol == IPPROTO_UDP) && (udp_sk(skb->sk)->encap_type == UDP_ENCAP_L2TPINUDP)) {
+				DEBUG_TRACE("Net device: %p PPP channel is PPPoL2TPV2\n", dest_dev);
+				break;
+			}
+#endif
 			/*
 			 * PPP - but what is the channel type?
 			 * First: If this is multi-link then we do not support it
@@ -2921,8 +3342,6 @@
 				break;
 			}
 
-			DEBUG_TRACE("Net device: %p is PPP\n", dest_dev);
-
 			/*
 			 * Get the PPP channel and then enquire what kind of channel it is
 			 * NOTE: Not multilink so only one channel to get.
@@ -2939,42 +3358,58 @@
 			 * NOTE: Not all PPP channels support channel specific methods.
 			 */
 			channel_protocol = ppp_channel_get_protocol(ppp_chan[0]);
-			if (channel_protocol != PX_PROTO_OE) {
-				DEBUG_TRACE("Net device: %p PPP channel protocol: %d - Unknown to the ECM\n",
-						dest_dev, channel_protocol);
+
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+			if (channel_protocol == PX_PROTO_OL2TP) {
 
 				/*
-				 * Release the channel
+				 * PPPoL2TPV2 channel
 				 */
 				ppp_release_channels(ppp_chan, 1);
+				DEBUG_TRACE("Net device: %p PPP channel is PPPoL2TPV2\n", dest_dev);
 
+				/*
+				 * Release the channel.  Note that next_dev not held.
+				 */
 				break;
 			}
+#endif
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
+			if (channel_protocol == PX_PROTO_OE) {
+				/*
+				 * PPPoE channel
+				 */
+				DEBUG_TRACE("Net device: %p PPP channel is PPPoE\n", dest_dev);
+
+				/*
+				 * Get PPPoE session information and the underlying device it is using.
+				 */
+				pppoe_channel_addressing_get(ppp_chan[0], &addressing);
+
+				/*
+				 * Copy the dev hold into this, we will release the hold later
+				 */
+				next_dev = addressing.dev;
+				next_dest_addr_valid = false;
+				next_dest_node_addr_valid = true;
+				memcpy(next_dest_node_addr, addressing.pa.remote, ETH_ALEN);
+
+				/*
+				 * Release the channel.  Note that next_dev is still (correctly) held.
+				 */
+				ppp_release_channels(ppp_chan, 1);
+				break;
+			}
+#endif
+
+			DEBUG_TRACE("Net device: %p PPP channel protocol: %d - Unknown to the ECM\n",
+				    dest_dev, channel_protocol);
 
 			/*
-			 * PPPoE channel
-			 */
-			DEBUG_TRACE("Net device: %p PPP channel is PPPoE\n", dest_dev);
-
-			/*
-			 * Get PPPoE session information and the underlying device it is using.
-			 */
-			pppoe_channel_addressing_get(ppp_chan[0], &addressing);
-
-			/*
-			 * Copy the dev hold into this, we will release the hold later
-			 */
-			next_dev = addressing.dev;
-			next_dest_addr_valid = false;
-			next_dest_node_addr_valid = true;
-			memcpy(next_dest_node_addr, addressing.pa.remote, ETH_ALEN);
-
-			DEBUG_TRACE("Net device: %p, next device: %p (%s)\n", dest_dev, next_dev, next_dev->name);
-
-			/*
-			 * Release the channel.  Note that next_dev is still (correctly) held.
+			 * Release the channel
 			 */
 			ppp_release_channels(ppp_chan, 1);
+
 #endif
 		} while (false);
 
@@ -3089,7 +3524,7 @@
 				br_dev_update_stats(dev, &stats);
 				break;
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			case ECM_DB_IFACE_TYPE_PPPOE:
 				DEBUG_INFO("PPPOE\n");
 				ppp_update_stats(dev, rx_packets, rx_bytes, tx_packets, tx_bytes);
@@ -3790,7 +4225,7 @@
 	/*
 	 * register for bridge fdb database modificationevents
 	 */
-        br_fdb_update_register_notify(&ecm_interface_node_br_fdb_update_nb);
+	br_fdb_update_register_notify(&ecm_interface_node_br_fdb_update_nb);
 #endif
 	return 0;
 }
diff --git a/ecm_interface.h b/ecm_interface.h
index b254355..1399603 100644
--- a/ecm_interface.h
+++ b/ecm_interface.h
@@ -51,14 +51,15 @@
 #ifdef ECM_IPV6_ENABLE
 struct neighbour *ecm_interface_ipv6_neigh_get(ip_addr_t addr);
 #endif
+bool ecm_interface_skip_l2tpv3_pptp(struct sk_buff *skb, const struct net_device *out);
 bool ecm_interface_skip_l2tp_pptp(struct sk_buff *skb, const struct net_device *out);
-struct ecm_db_iface_instance *ecm_interface_establish_and_ref(struct ecm_front_end_connection_instance *feci, struct net_device *dev);
+struct ecm_db_iface_instance *ecm_interface_establish_and_ref(struct ecm_front_end_connection_instance *feci, struct net_device *dev, struct sk_buff *skb);
 
 #ifdef ECM_MULTICAST_ENABLE
 int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_connection_instance *feci, struct ecm_db_iface_instance *interfaces, struct net_device *in_dev, ip_addr_t packet_src_addr, ip_addr_t packet_dest_addr, uint8_t maxvif, uint32_t *dst_dev, uint32_t *to_interface_first,
-__be16 *layer4hdr);
+__be16 *layer4hdr, struct sk_buff *skb);
 
-int32_t ecm_interface_multicast_heirarchy_construct_bridged(struct ecm_front_end_connection_instance *feci, struct ecm_db_iface_instance *interfaces, struct net_device *br_dev, ip_addr_t src_addr, ip_addr_t dest_addr, uint8_t mc_max_dst, int32_t *mc_dst_dev, uint32_t *to_interface_first, uint8_t *src_node_addr, __be16 *layer4hdr);
+int32_t ecm_interface_multicast_heirarchy_construct_bridged(struct ecm_front_end_connection_instance *feci, struct ecm_db_iface_instance *interfaces, struct net_device *br_dev, ip_addr_t src_addr, ip_addr_t dest_addr, uint8_t mc_max_dst, int32_t *mc_dst_dev, uint32_t *to_interface_first, uint8_t *src_node_addr, __be16 *layer4hdr, struct sk_buff *skb);
 
 void ecm_interface_multicast_stats_update(struct ecm_db_connection_instance *ci, uint32_t from_tx_packets, uint32_t from_tx_bytes, uint32_t from_rx_packets, uint32_t from_rx_bytes, uint32_t to_tx_packets, uint32_t to_tx_bytes, uint32_t to_rx_packets, uint32_t to_rx_bytes);
 
@@ -74,10 +75,11 @@
 					struct net_device *given_dest_dev, bool is_routed,
 					struct net_device *given_src_dev,
 					uint8_t *dest_node_addr, uint8_t *src_node_addr,
-					__be16 *layer4hdr);
+					__be16 *layer4hdr, struct sk_buff *skb);
 void ecm_interface_stats_update(struct ecm_db_connection_instance *ci, uint32_t from_tx_packets, uint32_t from_tx_bytes, uint32_t from_rx_packets, uint32_t from_rx_bytes, uint32_t to_tx_packets, uint32_t to_tx_bytes, uint32_t to_rx_packets, uint32_t to_rx_bytes);
 struct net_device *ecm_interface_dev_find_by_addr(ip_addr_t addr, bool *from_local_addr);
 void ecm_interface_stats_update(struct ecm_db_connection_instance *ci, uint32_t from_tx_packets, uint32_t from_tx_bytes, uint32_t from_rx_packets, uint32_t from_rx_bytes, uint32_t to_tx_packets, uint32_t to_tx_bytes, uint32_t to_rx_packets, uint32_t to_rx_bytes);
 
 struct net_device *ecm_interface_get_and_hold_dev_master(struct net_device *dev);
 void ecm_interface_dev_regenerate_connections(struct net_device *dev);
+struct net_device *ecm_interface_dev_find_by_local_addr(ip_addr_t addr);
diff --git a/ecm_types.h b/ecm_types.h
index b5f3221..44c0c26 100644
--- a/ecm_types.h
+++ b/ecm_types.h
@@ -36,7 +36,6 @@
 #define ECM_IP_ADDR_MATCH(a, b) \
 	((a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]))
 
-
 #define ECM_IP_ADDR_IS_V4(a) \
 	((a[1] == 0x0000ffff) && !a[2] && !a[3])
 
@@ -353,7 +352,6 @@
 	sprintf(str, ECM_IP_ADDR_DOT_FMT, ECM_IP_ADDR_TO_DOT(a));
 }
 
-
 /*
  * ecm_string_to_ip_addr()
  *	Convert a string IP address to its ECM ip_addr_t representation
diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c
index f22833f..815e1ca 100644
--- a/frontends/nss/ecm_nss_ipv4.c
+++ b/frontends/nss/ecm_nss_ipv4.c
@@ -180,7 +180,7 @@
 struct ecm_db_node_instance *ecm_nss_ipv4_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr)
+							uint8_t *given_node_addr, struct sk_buff *skb)
 {
 	struct ecm_db_node_instance *ni;
 	struct ecm_db_node_instance *nni;
@@ -188,6 +188,9 @@
 	int i;
 	bool done;
 	uint8_t node_addr[ETH_ALEN];
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+	ip_addr_t local_ip, remote_ip;
+#endif
 
 	DEBUG_INFO("Establish node for " ECM_IP_ADDR_DOT_FMT "\n", ECM_IP_ADDR_TO_DOT(addr));
 
@@ -208,20 +211,24 @@
 		done = true;
 		DEBUG_TRACE("Using given node address: %pM\n", node_addr);
 	}
+
 	for (i = ECM_DB_IFACE_HEIRARCHY_MAX - 1; (!done) && (i >= interface_list_first); i--) {
 		ecm_db_iface_type_t type;
 		ip_addr_t gw_addr = ECM_IP_ADDR_NULL;
 		bool on_link = false;
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 		struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+		struct ecm_db_interface_info_pppol2tpv2 pppol2tpv2_info;
+#endif
 		type = ecm_db_connection_iface_type_get(interface_list[i]);
 		DEBUG_INFO("Lookup node address, interface @ %d is type: %d\n", i, type);
 
 		switch (type) {
 
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * Node address is the address of the remote PPPoE server
 			 */
@@ -239,6 +246,31 @@
 			done = true;
 			break;
 
+		case ECM_DB_IFACE_TYPE_PPPOL2TPV2:
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+			ecm_db_iface_pppol2tpv2_session_info_get(interface_list[i], &pppol2tpv2_info);
+			ECM_HIN4_ADDR_TO_IP_ADDR(local_ip, pppol2tpv2_info.ip.saddr);
+			ECM_HIN4_ADDR_TO_IP_ADDR(remote_ip, pppol2tpv2_info.ip.daddr);
+			if (ECM_IP_ADDR_MATCH(local_ip, addr)) {
+				if (unlikely(!ecm_interface_mac_addr_get(local_ip, node_addr, &on_link, gw_addr))) {
+					DEBUG_TRACE("failed to obtain node address for " ECM_IP_ADDR_DOT_FMT "\n", ECM_IP_ADDR_TO_DOT(local_ip));
+					return NULL;
+				}
+
+			} else {
+				if (unlikely(!ecm_interface_mac_addr_get(remote_ip, node_addr, &on_link, gw_addr))) {
+					DEBUG_TRACE("failed to obtain node address for host " ECM_IP_ADDR_DOT_FMT "\n", ECM_IP_ADDR_TO_DOT(remote_ip));
+					return NULL;
+				}
+			}
+
+			done = true;
+			break;
+#else
+			DEBUG_TRACE("PPPoL2TPV2 interface unsupported\n");
+			return NULL;
+#endif
+
 		case ECM_DB_IFACE_TYPE_VLAN:
 #ifdef ECM_INTERFACE_VLAN_ENABLE
 			/*
@@ -300,7 +332,7 @@
 	/*
 	 * No node - establish iface
 	 */
-	ii = ecm_interface_establish_and_ref(feci, dev);
+	ii = ecm_interface_establish_and_ref(feci, dev, skb);
 	if (!ii) {
 		DEBUG_WARN("Failed to establish iface\n");
 		return NULL;
@@ -657,7 +689,7 @@
 void ecm_nss_ipv4_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
 							struct net_device *out_dev, struct net_device *out_dev_nat,
 							struct net_device *in_dev, struct net_device *in_dev_nat,
-							__be16 *layer4hdr)
+							__be16 *layer4hdr, struct sk_buff *skb)
 {
 	int i;
 	bool reclassify_allowed;
@@ -732,7 +764,7 @@
 	feci = ecm_db_connection_front_end_get_and_ref(ci);
 
 	DEBUG_TRACE("%p: Update the 'from' interface heirarchy list\n", ci);
-	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr);
+	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr, skb);
 	if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -742,10 +774,11 @@
 
 	DEBUG_TRACE("%p: Update the 'from NAT' interface heirarchy list\n", ci);
 	if ((protocol == IPPROTO_IPV6) || (protocol == IPPROTO_ESP)) {
-		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, layer4hdr);
+		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, layer4hdr, skb);
 	} else {
-		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr);
+		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr, skb);
 	}
+
 	if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -754,7 +787,7 @@
 	ecm_db_connection_interfaces_deref(from_nat_list, from_nat_list_first);
 
 	DEBUG_TRACE("%p: Update the 'to' interface heirarchy list\n", ci);
-	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr);
+	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr, skb);
 	if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -763,7 +796,7 @@
 	ecm_db_connection_interfaces_deref(to_list, to_list_first);
 
 	DEBUG_TRACE("%p: Update the 'to NAT' interface heirarchy list\n", ci);
-	to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr);
+	to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr, skb);
 	if (to_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -1312,6 +1345,14 @@
 #endif
 
 #ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+	/*
+	 * skip l2tpv3/pptp because we don't accelerate them
+	 */
+	if (ecm_interface_skip_l2tpv3_pptp(skb, out)) {
+		return NF_ACCEPT;
+	}
+#else
 	/*
 	 * skip l2tp/pptp because we don't accelerate them
 	 */
@@ -1319,6 +1360,7 @@
 		return NF_ACCEPT;
 	}
 #endif
+#endif
 
 	/*
 	 * Identify interface from where this packet came
@@ -1537,7 +1579,6 @@
 	result = ecm_nss_ipv4_ip_process((struct net_device *)out, in,
 				skb_eth_hdr->h_source, skb_eth_hdr->h_dest, can_accel, false, false, skb);
 
-
 	dev_put(in);
 	dev_put(bridge);
 	return result;
diff --git a/frontends/nss/ecm_nss_ipv4.h b/frontends/nss/ecm_nss_ipv4.h
index 65bc5c8..467ca74 100644
--- a/frontends/nss/ecm_nss_ipv4.h
+++ b/frontends/nss/ecm_nss_ipv4.h
@@ -171,11 +171,11 @@
 extern void ecm_nss_ipv4_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
 							struct net_device *out_dev, struct net_device *out_dev_nat,
 							struct net_device *in_dev, struct net_device *in_dev_nat,
-							__be16 *layer4hdr);
+							__be16 *layer4hdr, struct sk_buff *skb);
 extern struct ecm_db_node_instance *ecm_nss_ipv4_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr);
+							uint8_t *given_node_addr, struct sk_buff *skb);
 extern struct ecm_db_host_instance *ecm_nss_ipv4_host_establish_and_ref(ip_addr_t addr);
 extern struct ecm_db_mapping_instance *ecm_nss_ipv4_mapping_establish_and_ref(ip_addr_t addr, int port);
 extern int ecm_nss_ipv4_init(struct dentry *dentry);
diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c
index 99fb39f..59eec83 100644
--- a/frontends/nss/ecm_nss_ipv6.c
+++ b/frontends/nss/ecm_nss_ipv6.c
@@ -187,7 +187,7 @@
 struct ecm_db_node_instance *ecm_nss_ipv6_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr)
+							uint8_t *given_node_addr, struct sk_buff *skb)
 {
 	struct ecm_db_node_instance *ni;
 	struct ecm_db_node_instance *nni;
@@ -219,7 +219,7 @@
 		ecm_db_iface_type_t type;
 		ip_addr_t gw_addr = ECM_IP_ADDR_NULL;
 		bool on_link = false;
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 		struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 		type = ecm_db_connection_iface_type_get(interface_list[i]);
@@ -228,7 +228,7 @@
 		switch (type) {
 
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * Node address is the address of the remote PPPoE server
 			 */
@@ -305,7 +305,7 @@
 	/*
 	 * No node - establish iface
 	 */
-	ii = ecm_interface_establish_and_ref(feci, dev);
+	ii = ecm_interface_establish_and_ref(feci, dev, skb);
 	if (!ii) {
 		DEBUG_WARN("Failed to establish iface\n");
 		return NULL;
@@ -660,7 +660,7 @@
  * classifiers permit this operation.
  */
 void ecm_nss_ipv6_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
-							struct net_device *out_dev, struct net_device *in_dev)
+							struct net_device *out_dev, struct net_device *in_dev, struct sk_buff *skb)
 {
 	int i;
 	bool reclassify_allowed;
@@ -719,7 +719,7 @@
 	feci = ecm_db_connection_front_end_get_and_ref(ci);
 
 	DEBUG_TRACE("%p: Update the 'from' interface heirarchy list\n", ci);
-	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 	if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv6_retry_regen;
 	}
@@ -728,7 +728,7 @@
 	ecm_db_connection_interfaces_deref(from_list, from_list_first);
 
 	DEBUG_TRACE("%p: Update the 'to' interface heirarchy list\n", ci);
-	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 	if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv6_retry_regen;
 	}
diff --git a/frontends/nss/ecm_nss_ipv6.h b/frontends/nss/ecm_nss_ipv6.h
index 35663d5..bcbf112 100644
--- a/frontends/nss/ecm_nss_ipv6.h
+++ b/frontends/nss/ecm_nss_ipv6.h
@@ -169,11 +169,11 @@
 extern struct ecm_classifier_instance *ecm_nss_ipv6_assign_classifier(struct ecm_db_connection_instance *ci, ecm_classifier_type_t type);
 extern bool ecm_nss_ipv6_reclassify(struct ecm_db_connection_instance *ci, int assignment_count, struct ecm_classifier_instance *assignments[]);
 extern void ecm_nss_ipv6_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
-							struct net_device *out_dev, struct net_device *in_dev);
+							struct net_device *out_dev, struct net_device *in_dev, struct sk_buff *skb);
 extern struct ecm_db_node_instance *ecm_nss_ipv6_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr);
+							uint8_t *given_node_addr, struct sk_buff *skb);
 extern struct ecm_db_host_instance *ecm_nss_ipv6_host_establish_and_ref(ip_addr_t addr);
 extern struct ecm_db_mapping_instance *ecm_nss_ipv6_mapping_establish_and_ref(ip_addr_t addr, int port);
 extern int ecm_nss_ipv6_init(struct dentry *dentry);
diff --git a/frontends/nss/ecm_nss_multicast_ipv4.c b/frontends/nss/ecm_nss_multicast_ipv4.c
index 4d9580c..cb5f33f 100644
--- a/frontends/nss/ecm_nss_multicast_ipv4.c
+++ b/frontends/nss/ecm_nss_multicast_ipv4.c
@@ -115,13 +115,13 @@
 								      struct ecm_db_iface_instance *interfaces, ip_addr_t ip_src_addr, ip_addr_t ip_dest_addr,
 								      struct net_device *in_dev, struct net_device *brdev, uint8_t max_if, uint32_t *dst_dev,
 								      uint32_t *to_list_first, uint8_t *src_node_addr, bool is_routed,
-								      __be16 *layer4hdr)
+								      __be16 *layer4hdr, struct sk_buff *skb)
 {
 	int interface_instance_cnt;
 	if (is_routed) {
-		interface_instance_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, interfaces, in_dev, ip_src_addr, ip_dest_addr, max_if, dst_dev, to_list_first, layer4hdr);
+		interface_instance_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, interfaces, in_dev, ip_src_addr, ip_dest_addr, max_if, dst_dev, to_list_first, layer4hdr, skb);
 	} else {
-		interface_instance_cnt = ecm_interface_multicast_heirarchy_construct_bridged(feci, interfaces, brdev, ip_src_addr, ip_dest_addr, max_if, dst_dev, to_list_first, src_node_addr, layer4hdr);
+		interface_instance_cnt = ecm_interface_multicast_heirarchy_construct_bridged(feci, interfaces, brdev, ip_src_addr, ip_dest_addr, max_if, dst_dev, to_list_first, src_node_addr, layer4hdr, skb);
 	}
 
 	return interface_instance_cnt;
@@ -536,7 +536,7 @@
 			 * Conflicting information may cause accel to be unsupported.
 			 */
 			switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -586,7 +586,7 @@
 				DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nmci, to_nss_iface_address);
 				break;
 			case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				/*
 				 * More than one PPPoE in the list is not valid!
 				 */
@@ -950,7 +950,7 @@
 #ifdef ECM_INTERFACE_VLAN_ENABLE
 			struct ecm_db_interface_info_vlan vlan_info;
 #endif
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 		case ECM_DB_IFACE_TYPE_BRIDGE:
@@ -979,7 +979,7 @@
 #endif
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -1016,7 +1016,6 @@
 		return;
 	}
 
-
 	from_nat_ifaces_first = ecm_db_connection_from_nat_interfaces_get_and_ref(feci->ci, from_nat_ifaces);
 	from_nat_ifaces_identifier = ecm_db_iface_interface_identifier_get(from_nat_ifaces[ECM_DB_IFACE_HEIRARCHY_MAX - 1]);
 	ecm_db_connection_interfaces_deref(from_nat_ifaces, from_nat_ifaces_first);
@@ -1068,7 +1067,7 @@
 			 * Conflicting information may cause accel to be unsupported.
 			 */
 			switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -1122,7 +1121,7 @@
 				DEBUG_TRACE("%p: Ethernet - mac: %pM, mtu %d\n", nmci, to_nss_iface_address, to_mtu);
 				break;
 			case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				/*
 				 * More than one PPPoE in the list is not valid!
 				 */
@@ -1939,7 +1938,7 @@
 	layer4hdr[1] = htons(port);
 
 	DEBUG_TRACE("%p: Update the 'from' interface heirarchy list\n", ci);
-	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr);
+	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr, NULL);
 	if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_multicast_ipv4_retry_regen;
 	}
@@ -1948,7 +1947,7 @@
 	ecm_db_connection_interfaces_deref(from_list, from_list_first);
 
 	DEBUG_TRACE("%p: Update the 'from NAT' interface heirarchy list\n", ci);
-	from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr, layer4hdr);
+	from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr, layer4hdr, NULL);
 	if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_multicast_ipv4_retry_regen;
 	}
@@ -2326,7 +2325,6 @@
 		}
 	}
 
-
 	DEBUG_TRACE("MCAST UDP src: " ECM_IP_ADDR_DOT_FMT ":%d, dest: " ECM_IP_ADDR_DOT_FMT ":%d, dir %d\n",
 			ECM_IP_ADDR_TO_DOT(ip_src_addr), src_port, ECM_IP_ADDR_TO_DOT(ip_dest_addr), dest_port, ecm_dir);
 
@@ -2416,7 +2414,7 @@
 		 * For this we also need the interface lists which we also set upon the new connection while we are at it.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, (__be16 *)&udp_hdr);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, (__be16 *)&udp_hdr, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -2427,7 +2425,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Establish source node\n", nci);
-		src_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			DEBUG_WARN("%p: Failed to establish source node\n", nci);
@@ -2483,7 +2481,7 @@
 
 		interface_idx_cnt = ecm_nss_multicast_connection_to_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, in_dev,
 												  out_dev->master, if_cnt, dst_dev, to_list_first,
-												  src_node_addr, is_routed, (__be16 *)&udp_hdr);
+												  src_node_addr, is_routed, (__be16 *)&udp_hdr, skb);
 		if (interface_idx_cnt == 0) {
 			ecm_db_node_deref(src_ni);
 			ecm_db_mapping_deref(src_mi);
@@ -2517,7 +2515,7 @@
 
 		DEBUG_TRACE("%p: Create destination node\n", nci);
 		ecm_db_multicast_copy_if_heirarchy(to_list_temp, to_list);
-		dest_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list_temp, *to_list_first, dest_mac_addr);
+		dest_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list_temp, *to_list_first, dest_mac_addr, skb);
 
 		/*
 		 * De-ref the Multicast destination interface list
@@ -2564,7 +2562,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'from NAT' interface heirarchy list\n", nci);
-		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr, dest_node_addr, (__be16 *)&udp_hdr);
+		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr, dest_node_addr, (__be16 *)&udp_hdr, skb);
 		if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			for (vif = 0; vif < ECM_DB_MULTICAST_IF_MAX; vif++) {
 				to_list_single = ecm_db_multicast_if_heirarchy_get(to_list, vif);
@@ -2587,7 +2585,7 @@
 		}
 		ecm_db_connection_from_nat_interfaces_reset(nci, from_nat_list, from_nat_list_first);
 
-		src_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr);
+		src_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_nat_list, from_nat_list_first);
 		if (!src_nat_ni) {
 			for (vif = 0; vif < ECM_DB_MULTICAST_IF_MAX; vif++) {
@@ -2808,7 +2806,7 @@
 			feci = ecm_db_connection_front_end_get_and_ref(ci);
 			interface_idx_cnt = ecm_nss_multicast_connection_to_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, in_dev,
 													  out_dev->master, if_cnt, dst_dev, to_list_first,
-													  src_node_addr, is_routed, (__be16 *)&udp_hdr);
+													  src_node_addr, is_routed, (__be16 *)&udp_hdr, skb);
 			feci->deref(feci);
 			if (interface_idx_cnt == 0) {
 				DEBUG_WARN("Failed to reconstruct 'to mc' heirarchy list\n");
@@ -3241,7 +3239,7 @@
 			port = (__be16)(ecm_db_connection_to_port_get(ci));
 			layer4hdr[1] = htons(port);
 
-			if_cnt = ecm_interface_multicast_heirarchy_construct_bridged(feci, to_list, brdev, src_ip, dest_ip, mc_update.if_join_cnt, mc_update.join_dev, to_list_first, src_node_addr, layer4hdr);
+			if_cnt = ecm_interface_multicast_heirarchy_construct_bridged(feci, to_list, brdev, src_ip, dest_ip, mc_update.if_join_cnt, mc_update.join_dev, to_list_first, src_node_addr, layer4hdr, NULL);
 			if (if_cnt == 0) {
 				DEBUG_WARN("Failed to obtain 'to_mcast_update' heirarchy list\n");
 				feci->deref(feci);
@@ -3360,7 +3358,6 @@
 
 	DEBUG_TRACE("origin : group " ECM_IP_ADDR_DOT_FMT ":" ECM_IP_ADDR_DOT_FMT "\n", ECM_IP_ADDR_TO_DOT(src_ip), ECM_IP_ADDR_TO_DOT(dest_ip));
 
-
 	/*
 	 * Access the 5-tuple information from the tuple_instance table, using the
 	 * source and group addresses
@@ -3457,7 +3454,7 @@
 			port = (__be16)(ecm_db_connection_to_port_get(ci));
 			layer4hdr[1] = htons(port);
 
-			vif_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, to_list, NULL, src_ip, dest_ip, mc_update.if_join_cnt, mc_update.join_dev, to_list_first, layer4hdr);
+			vif_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, to_list, NULL, src_ip, dest_ip, mc_update.if_join_cnt, mc_update.join_dev, to_list_first, layer4hdr, NULL);
 			if (vif_cnt == 0) {
 				DEBUG_WARN("Failed to obtain 'to_mcast_update' heirarchy list\n");
 				feci->deref(feci);
diff --git a/frontends/nss/ecm_nss_multicast_ipv6.c b/frontends/nss/ecm_nss_multicast_ipv6.c
index be47589..992b0e8 100644
--- a/frontends/nss/ecm_nss_multicast_ipv6.c
+++ b/frontends/nss/ecm_nss_multicast_ipv6.c
@@ -116,16 +116,17 @@
 static int ecm_nss_multicast_ipv6_interface_heirarchy_construct(struct ecm_front_end_connection_instance *feci,
 								struct ecm_db_iface_instance *interfaces, struct net_device *in_dev,
 								struct net_device *brdev, ip_addr_t packet_src_addr, ip_addr_t packet_dest_addr, uint8_t max_if,
-								uint32_t *dst_dev, int32_t *to_interface_first, uint8_t *src_node_addr, bool is_routed)
+								uint32_t *dst_dev, int32_t *to_interface_first, uint8_t *src_node_addr, bool is_routed,
+								struct sk_buff *skb)
 {
 	int32_t iface_instance_cnt;
 
 	if (is_routed) {
-		iface_instance_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, interfaces, in_dev, packet_src_addr, packet_dest_addr, max_if, dst_dev, to_interface_first, NULL);
+		iface_instance_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, interfaces, in_dev, packet_src_addr, packet_dest_addr, max_if, dst_dev, to_interface_first, NULL, skb);
 	} else {
 		iface_instance_cnt = ecm_interface_multicast_heirarchy_construct_bridged(feci, interfaces, brdev,
 											 packet_src_addr, packet_dest_addr, max_if,
-											 dst_dev, to_interface_first, src_node_addr, NULL);
+											 dst_dev, to_interface_first, src_node_addr, NULL, skb);
 	}
 	return iface_instance_cnt;
 }
@@ -540,7 +541,7 @@
 			 * Conflicting information may cause accel to be unsupported.
 			 */
 			switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -591,7 +592,7 @@
 				DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nmci, to_nss_iface_address);
 				break;
 			case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				/*
 				 * More than one PPPoE in the list is not valid!
 				 */
@@ -724,7 +725,6 @@
 	ecm_db_connection_from_address_get(feci->ci, addr);
 	ECM_IP_ADDR_TO_NSS_IPV6_ADDR(create->tuple.flow_ip, addr);
 
-
 	/*
 	 * The destination address is what the destination IP is translated to as it is forwarded to the next interface.
 	 * For egress this would yield the normal wan host and for ingress this would correctly NAT back to the LAN host
@@ -998,7 +998,6 @@
 		return;
 	}
 
-
 	/*
 	 * Now examine the TO / DEST heirarchy list to construct the destination part of the rule
 	 */
@@ -1036,7 +1035,7 @@
 			 * Conflicting information may cause accel to be unsupported.
 			 */
 			switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -1092,7 +1091,7 @@
 				DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nmci, to_nss_iface_address);
 				break;
 			case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 				/*
 				 * More than one PPPoE in the list is not valid!
 				 */
@@ -1231,7 +1230,6 @@
 	ecm_db_connection_from_address_get(feci->ci, addr);
 	ECM_IP_ADDR_TO_NSS_IPV6_ADDR(create->tuple.flow_ip, addr);
 
-
 	/*
 	 * The destination address is what the destination IP is translated to as it is forwarded to the next interface.
 	 * For egress this would yield the normal wan host and for ingress this would correctly NAT back to the LAN host
@@ -1578,7 +1576,6 @@
 			ECM_IP_ADDR_TO_OCTAL(src_ip), nirdm->tuple.flow_ident,
 			ECM_IP_ADDR_TO_OCTAL(dest_ip), nirdm->tuple.return_ident);
 
-
 	/*
 	 * Right place to free the multicast destination interfaces list.
 	 */
@@ -1886,7 +1883,7 @@
 	feci = ecm_db_connection_front_end_get_and_ref(ci);
 
 	DEBUG_TRACE("%p: Update the 'from' interface heirarchy list\n", ci);
-	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, NULL);
 	if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_multicast_ipv6_retry_regen;
 	}
@@ -2312,7 +2309,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, IPPROTO_UDP, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, IPPROTO_UDP, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -2323,7 +2320,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_nss_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_nss_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -2378,7 +2375,7 @@
 		}
 
 		interface_idx_cnt = ecm_nss_multicast_ipv6_interface_heirarchy_construct(feci, to_list, in_dev, out_dev->master, ip_src_addr,
-										      ip_dest_addr, mc_if_cnt, mc_dest_if, to_list_first, src_node_addr,  is_routed);
+										      ip_dest_addr, mc_if_cnt, mc_dest_if, to_list_first, src_node_addr,  is_routed, skb);
 		if (interface_idx_cnt == 0) {
 			DEBUG_WARN("Failed to obtain 'to' heirarchy list\n");
 			ecm_db_mapping_deref(src_mi);
@@ -2422,7 +2419,7 @@
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
 		ecm_db_multicast_copy_if_heirarchy(to_list_temp, to_list);
-		dest_ni = ecm_nss_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list_temp, *to_list_first, dest_mac_addr);
+		dest_ni = ecm_nss_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list_temp, *to_list_first, dest_mac_addr, skb);
 		if (!dest_ni) {
 			for (vif = 0; vif < ECM_DB_MULTICAST_IF_MAX; vif++) {
 				to_list_single = ecm_db_multicast_if_heirarchy_get(to_list, vif);
@@ -2632,7 +2629,8 @@
 			feci = ecm_db_connection_front_end_get_and_ref(ci);
 			interface_idx_cnt = ecm_nss_multicast_ipv6_interface_heirarchy_construct(feci, to_list, in_dev, out_dev->master,\
 												   ip_src_addr, ip_dest_addr, mc_if_cnt,\
-												   mc_dest_if, to_list_first, src_node_addr, is_routed);
+												   mc_dest_if, to_list_first, src_node_addr,
+												   is_routed, skb);
 			feci->deref(feci);
 			if (interface_idx_cnt == 0) {
 				DEBUG_WARN("Failed to reconstruct 'to mc' heirarchy list\n");
@@ -2895,7 +2893,6 @@
 	uint32_t mc_max_dst = ECM_DB_MULTICAST_IF_MAX;
 	uint32_t mc_dst_dev[ECM_DB_MULTICAST_IF_MAX];
 
-
 	memcpy(&group6, group, sizeof(struct in6_addr));
 	ECM_NIN6_ADDR_TO_IP_ADDR(dest_ip, group6);
 
@@ -3051,7 +3048,7 @@
 			 * Create the interface heirarchy list for the new interfaces. We append this list later to
 			 * the existing list of destination interfaces.
 			 */
-			if_cnt = ecm_interface_multicast_heirarchy_construct_bridged(feci, to_list, brdev, src_ip, dest_ip, mc_sync.if_join_cnt, mc_sync.join_dev, to_list_first, src_node_addr, NULL);
+			if_cnt = ecm_interface_multicast_heirarchy_construct_bridged(feci, to_list, brdev, src_ip, dest_ip, mc_sync.if_join_cnt, mc_sync.join_dev, to_list_first, src_node_addr, NULL, NULL);
 			if (if_cnt == 0) {
 				DEBUG_WARN("Failed to obtain 'to_mcast_update' heirarchy list\n");
 				feci->deref(feci);
@@ -3259,7 +3256,7 @@
 			 * Create the interface heirarchy list for the new interfaces. We append this list later to
 			 * the existing list of destination interfaces.
 			 */
-			vif_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, to_list, NULL, src_ip, dest_ip, mc_sync.if_join_cnt, mc_sync.join_dev, to_list_first, NULL);
+			vif_cnt = ecm_interface_multicast_heirarchy_construct_routed(feci, to_list, NULL, src_ip, dest_ip, mc_sync.if_join_cnt, mc_sync.join_dev, to_list_first, NULL, NULL);
 			if (vif_cnt == 0) {
 				DEBUG_WARN("Failed to obtain 'to_mcast_update' heirarchy list\n");
 				feci->deref(feci);
diff --git a/frontends/nss/ecm_nss_non_ported_ipv4.c b/frontends/nss/ecm_nss_non_ported_ipv4.c
index ef79e3d..cdeb75d 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_non_ported_ipv4.c
@@ -524,7 +524,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -563,7 +563,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, from_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -691,7 +691,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -730,7 +730,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, to_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -1853,7 +1853,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -1863,7 +1863,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -1883,7 +1883,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -1895,7 +1895,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -1930,9 +1930,9 @@
 		 */
 		DEBUG_TRACE("%p: Create the 'from NAT' interface heirarchy list\n", nci);
 		if ((protocol == IPPROTO_IPV6) || (protocol == IPPROTO_ESP)) {
-			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL);
+			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL, skb);
 		} else {
-			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL);
+			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL, skb);
 		}
 
 		if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
@@ -1948,7 +1948,7 @@
 		ecm_db_connection_from_nat_interfaces_reset(nci, from_nat_list, from_nat_list_first);
 
 		DEBUG_TRACE("%p: Create source nat node\n", nci);
-		src_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat);
+		src_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(from_nat_list, from_nat_list_first);
 		if (!src_nat_ni) {
 			ecm_db_mapping_deref(dest_mi);
@@ -1975,7 +1975,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to NAT' interface heirarchy list\n", nci);
-		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, NULL);
+		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, NULL, skb);
 		if (to_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_nat_mi);
 			ecm_db_node_deref(src_nat_ni);
@@ -1991,7 +1991,7 @@
 		ecm_db_connection_to_nat_interfaces_reset(nci, to_nat_list, to_nat_list_first);
 
 		DEBUG_TRACE("%p: Create dest nat node\n", nci);
-		dest_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat);
+		dest_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(to_nat_list, to_nat_list_first);
 		if (!dest_nat_ni) {
 			ecm_db_mapping_deref(src_nat_mi);
@@ -2151,7 +2151,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_nss_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, NULL);
+		ecm_nss_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, NULL, skb);
 	}
 
 	/*
diff --git a/frontends/nss/ecm_nss_non_ported_ipv6.c b/frontends/nss/ecm_nss_non_ported_ipv6.c
index 5ead02a..87f9795 100644
--- a/frontends/nss/ecm_nss_non_ported_ipv6.c
+++ b/frontends/nss/ecm_nss_non_ported_ipv6.c
@@ -460,7 +460,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -500,7 +500,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, from_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -628,7 +628,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -667,7 +667,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, to_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -1731,7 +1731,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -1741,7 +1741,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_nss_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_nss_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -1761,7 +1761,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -1773,7 +1773,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_nss_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_nss_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -1914,7 +1914,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_nss_ipv6_connection_regenerate(ci, sender, out_dev, in_dev);
+		ecm_nss_ipv6_connection_regenerate(ci, sender, out_dev, in_dev, skb);
 	}
 
 	/*
diff --git a/frontends/nss/ecm_nss_ported_ipv4.c b/frontends/nss/ecm_nss_ported_ipv4.c
index c8cd25a..aa03277 100644
--- a/frontends/nss/ecm_nss_ported_ipv4.c
+++ b/frontends/nss/ecm_nss_ported_ipv4.c
@@ -330,6 +330,9 @@
 	uint8_t from_nss_iface_address[ETH_ALEN];
 	uint8_t to_nss_iface_address[ETH_ALEN];
 	ip_addr_t addr;
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+	struct net_device *dev;
+#endif
 	struct nss_ipv4_msg nim;
 	struct nss_ipv4_rule_create_msg *nircm;
 	struct ecm_classifier_instance *assignments[ECM_CLASSIFIER_TYPES];
@@ -455,7 +458,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -500,7 +503,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, from_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -591,6 +594,33 @@
 			DEBUG_TRACE("%p: IPSEC - unsupported\n", npci);
 #endif
 			break;
+
+		case ECM_DB_IFACE_TYPE_PPPOL2TPV2:
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+			/*
+			 * l2tp packets from lan to wan gets routed twice.
+			 *	1. eth1-->br-lan to l2tp
+			 *	2. l2tp ---> eth0.
+			 * we need to push nss rule for both. Requirement
+			 * mandidates multiple session per tunnel and all tunnel
+			 * packets has same 5 tuple info. So need to create a
+			 * special static l2tp interface with nss to identify
+			 * packets from wan side. So l2tp--->eth0 rule to be
+			 * pushed with this static interface.
+			 */
+			ecm_db_connection_from_address_get(feci->ci, addr);
+			dev = ecm_interface_dev_find_by_local_addr(addr);
+			if (likely(dev)) {
+				dev_put(dev);
+				from_nss_iface_id =  NSS_L2TPV2_INTERFACE;
+				nircm->conn_rule.flow_interface_num = from_nss_iface_id;
+			}
+#else
+			rule_invalid = true;
+			DEBUG_TRACE("%p: L2TPV2 - unsupported\n", npci);
+#endif
+			break;
+
 		default:
 			DEBUG_TRACE("%p: Ignoring: %d (%s)\n", npci, ii_type, ii_name);
 		}
@@ -628,7 +658,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -673,7 +703,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, to_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -899,6 +929,19 @@
 	nircm->conn_rule.flow_mtu = (uint32_t)ecm_db_connection_from_iface_mtu_get(feci->ci);
 	nircm->conn_rule.return_mtu = (uint32_t)ecm_db_connection_to_iface_mtu_get(feci->ci);
 
+#ifdef ECM_INTERFACE_L2TPV2_ENABLE
+	/*
+	 * pppd sets the mtu of l2tp interface. This
+	 * depends on configuration. We have to set the
+	 * static interface mtu as maximum.
+	 * Else l2tp static interface in firmware may reject
+	 * packets from wan side.
+	 */
+	if (unlikely(from_nss_iface_id ==  NSS_L2TPV2_INTERFACE)) {
+		nircm->conn_rule.flow_mtu = 1500;
+	}
+#endif
+
 	if (protocol == IPPROTO_TCP) {
 		/*
 		 * Need window scaling and remarking information if available
@@ -2009,7 +2052,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -2019,7 +2062,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -2039,7 +2082,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -2051,7 +2094,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -2081,7 +2124,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from NAT' interface heirarchy list\n", nci);
-		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr);
+		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr, skb);
 		if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(dest_mi);
 			ecm_db_node_deref(dest_ni);
@@ -2095,7 +2138,7 @@
 		ecm_db_connection_from_nat_interfaces_reset(nci, from_nat_list, from_nat_list_first);
 
 		DEBUG_TRACE("%p: Create source nat node\n", nci);
-		src_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat);
+		src_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(from_nat_list, from_nat_list_first);
 		if (!src_nat_ni) {
 			ecm_db_mapping_deref(dest_mi);
@@ -2122,7 +2165,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to NAT' interface heirarchy list\n", nci);
-		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr);
+		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr, skb);
 		if (to_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_nat_mi);
 			ecm_db_node_deref(src_nat_ni);
@@ -2138,7 +2181,7 @@
 		ecm_db_connection_to_nat_interfaces_reset(nci, to_nat_list, to_nat_list_first);
 
 		DEBUG_TRACE("%p: Create dest nat node\n", nci);
-		dest_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat);
+		dest_nat_ni = ecm_nss_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(to_nat_list, to_nat_list_first);
 		if (!dest_nat_ni) {
 			ecm_db_mapping_deref(src_nat_mi);
@@ -2298,7 +2341,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_nss_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, layer4hdr);
+		ecm_nss_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, layer4hdr, skb);
 	}
 
 	/*
diff --git a/frontends/nss/ecm_nss_ported_ipv6.c b/frontends/nss/ecm_nss_ported_ipv6.c
index bd73968..da0ac44 100644
--- a/frontends/nss/ecm_nss_ported_ipv6.c
+++ b/frontends/nss/ecm_nss_ported_ipv6.c
@@ -460,7 +460,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -505,7 +505,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, from_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -633,7 +633,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -678,7 +678,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, to_nss_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -1916,7 +1916,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -1926,7 +1926,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_nss_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_nss_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -1946,7 +1946,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -1958,7 +1958,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_nss_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_nss_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -2099,7 +2099,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_nss_ipv6_connection_regenerate(ci, sender, out_dev, in_dev);
+		ecm_nss_ipv6_connection_regenerate(ci, sender, out_dev, in_dev, skb);
 	}
 
 	/*
diff --git a/frontends/sfe/ecm_sfe_ipv4.c b/frontends/sfe/ecm_sfe_ipv4.c
index b761fbe..f948989 100644
--- a/frontends/sfe/ecm_sfe_ipv4.c
+++ b/frontends/sfe/ecm_sfe_ipv4.c
@@ -168,7 +168,7 @@
 struct ecm_db_node_instance *ecm_sfe_ipv4_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr)
+							uint8_t *given_node_addr, struct sk_buff *skb)
 {
 	struct ecm_db_node_instance *ni;
 	struct ecm_db_node_instance *nni;
@@ -200,7 +200,7 @@
 		ecm_db_iface_type_t type;
 		ip_addr_t gw_addr = ECM_IP_ADDR_NULL;
 		bool on_link = false;
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 		struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 		type = ecm_db_connection_iface_type_get(interface_list[i]);
@@ -209,7 +209,7 @@
 		switch (type) {
 
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * Node address is the address of the remote PPPoE server
 			 */
@@ -288,7 +288,7 @@
 	/*
 	 * No node - establish iface
 	 */
-	ii = ecm_interface_establish_and_ref(feci, dev);
+	ii = ecm_interface_establish_and_ref(feci, dev, skb);
 	if (!ii) {
 		DEBUG_WARN("Failed to establish iface\n");
 		return NULL;
@@ -645,7 +645,7 @@
 void ecm_sfe_ipv4_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
 							struct net_device *out_dev, struct net_device *out_dev_nat,
 							struct net_device *in_dev, struct net_device *in_dev_nat,
-							__be16 *layer4hdr)
+							__be16 *layer4hdr, struct sk_buff *skb)
 {
 	int i;
 	bool reclassify_allowed;
@@ -720,7 +720,7 @@
 	feci = ecm_db_connection_front_end_get_and_ref(ci);
 
 	DEBUG_TRACE("%p: Update the 'from' interface heirarchy list\n", ci);
-	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr);
+	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr, skb);
 	if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -729,7 +729,7 @@
 	ecm_db_connection_interfaces_deref(from_list, from_list_first);
 
 	DEBUG_TRACE("%p: Update the 'from NAT' interface heirarchy list\n", ci);
-	from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr);
+	from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr, skb);
 	if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -738,7 +738,7 @@
 	ecm_db_connection_interfaces_deref(from_nat_list, from_nat_list_first);
 
 	DEBUG_TRACE("%p: Update the 'to' interface heirarchy list\n", ci);
-	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr);
+	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr, skb);
 	if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -747,7 +747,7 @@
 	ecm_db_connection_interfaces_deref(to_list, to_list_first);
 
 	DEBUG_TRACE("%p: Update the 'to NAT' interface heirarchy list\n", ci);
-	to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr);
+	to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr, skb);
 	if (to_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv4_retry_regen;
 	}
@@ -1309,7 +1309,7 @@
 	}
 #endif
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 	/*
 	 * skip l2tp/pptp because we don't accelerate them
 	 */
@@ -1427,7 +1427,7 @@
 	}
 #endif
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 	/*
 	 * skip l2tp/pptp because we don't accelerate them
 	 */
@@ -1535,7 +1535,6 @@
 	result = ecm_sfe_ipv4_ip_process((struct net_device *)out, in,
 				skb_eth_hdr->h_source, skb_eth_hdr->h_dest, can_accel, false, false, skb);
 
-
 	dev_put(in);
 	dev_put(bridge);
 	return result;
diff --git a/frontends/sfe/ecm_sfe_ipv4.h b/frontends/sfe/ecm_sfe_ipv4.h
index 32b0477..3505c3e 100644
--- a/frontends/sfe/ecm_sfe_ipv4.h
+++ b/frontends/sfe/ecm_sfe_ipv4.h
@@ -170,11 +170,11 @@
 extern bool ecm_sfe_ipv4_reclassify(struct ecm_db_connection_instance *ci, int assignment_count, struct ecm_classifier_instance *assignments[]);
 extern void ecm_sfe_ipv4_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
 							struct net_device *out_dev, struct net_device *out_dev_nat,
-							struct net_device *in_dev, struct net_device *in_dev_nat, __be16 *layer4hdr);
+							struct net_device *in_dev, struct net_device *in_dev_nat, __be16 *layer4hdr, struct sk_buff *skb);
 extern struct ecm_db_node_instance *ecm_sfe_ipv4_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr);
+							uint8_t *given_node_addr, struct sk_buff *skb);
 extern struct ecm_db_host_instance *ecm_sfe_ipv4_host_establish_and_ref(ip_addr_t addr);
 extern struct ecm_db_mapping_instance *ecm_sfe_ipv4_mapping_establish_and_ref(ip_addr_t addr, int port);
 extern int ecm_sfe_ipv4_init(struct dentry *dentry);
diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c
index d6db14c..1a42e58 100644
--- a/frontends/sfe/ecm_sfe_ipv6.c
+++ b/frontends/sfe/ecm_sfe_ipv6.c
@@ -173,7 +173,7 @@
 struct ecm_db_node_instance *ecm_sfe_ipv6_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr)
+							uint8_t *given_node_addr, struct sk_buff *skb)
 {
 	struct ecm_db_node_instance *ni;
 	struct ecm_db_node_instance *nni;
@@ -205,7 +205,7 @@
 		ecm_db_iface_type_t type;
 		ip_addr_t gw_addr = ECM_IP_ADDR_NULL;
 		bool on_link = false;
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 		struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 		type = ecm_db_connection_iface_type_get(interface_list[i]);
@@ -214,7 +214,7 @@
 		switch (type) {
 
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * Node address is the address of the remote PPPoE server
 			 */
@@ -291,7 +291,7 @@
 	/*
 	 * No node - establish iface
 	 */
-	ii = ecm_interface_establish_and_ref(feci, dev);
+	ii = ecm_interface_establish_and_ref(feci, dev, skb);
 	if (!ii) {
 		DEBUG_WARN("Failed to establish iface\n");
 		return NULL;
@@ -646,7 +646,7 @@
  * classifiers permit this operation.
  */
 void ecm_sfe_ipv6_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
-							struct net_device *out_dev, struct net_device *in_dev)
+							struct net_device *out_dev, struct net_device *in_dev, struct sk_buff *skb)
 {
 	int i;
 	bool reclassify_allowed;
@@ -705,7 +705,7 @@
 	feci = ecm_db_connection_front_end_get_and_ref(ci);
 
 	DEBUG_TRACE("%p: Update the 'from' interface heirarchy list\n", ci);
-	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+	from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 	if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv6_retry_regen;
 	}
@@ -714,7 +714,7 @@
 	ecm_db_connection_interfaces_deref(from_list, from_list_first);
 
 	DEBUG_TRACE("%p: Update the 'to' interface heirarchy list\n", ci);
-	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+	to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 	if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 		goto ecm_ipv6_retry_regen;
 	}
@@ -1039,7 +1039,7 @@
 	}
 #endif
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 	/*
 	 * skip l2tp/pptp because we don't accelerate them
 	 */
@@ -1156,7 +1156,7 @@
 	}
 #endif
 
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 	/*
 	 * skip l2tp/pptp because we don't accelerate them
 	 */
diff --git a/frontends/sfe/ecm_sfe_ipv6.h b/frontends/sfe/ecm_sfe_ipv6.h
index 05ed372..f8b30f0 100644
--- a/frontends/sfe/ecm_sfe_ipv6.h
+++ b/frontends/sfe/ecm_sfe_ipv6.h
@@ -169,11 +169,11 @@
 extern struct ecm_classifier_instance *ecm_sfe_ipv6_assign_classifier(struct ecm_db_connection_instance *ci, ecm_classifier_type_t type);
 extern bool ecm_sfe_ipv6_reclassify(struct ecm_db_connection_instance *ci, int assignment_count, struct ecm_classifier_instance *assignments[]);
 extern void ecm_sfe_ipv6_connection_regenerate(struct ecm_db_connection_instance *ci, ecm_tracker_sender_type_t sender,
-							struct net_device *out_dev, struct net_device *in_dev);
+							struct net_device *out_dev, struct net_device *in_dev, struct sk_buff *skb);
 extern struct ecm_db_node_instance *ecm_sfe_ipv6_node_establish_and_ref(struct ecm_front_end_connection_instance *feci,
 							struct net_device *dev, ip_addr_t addr,
 							struct ecm_db_iface_instance *interface_list[], int32_t interface_list_first,
-							uint8_t *given_node_addr);
+							uint8_t *given_node_addr, struct sk_buff *skb);
 extern struct ecm_db_host_instance *ecm_sfe_ipv6_host_establish_and_ref(ip_addr_t addr);
 extern struct ecm_db_mapping_instance *ecm_sfe_ipv6_mapping_establish_and_ref(ip_addr_t addr, int port);
 extern int ecm_sfe_ipv6_init(struct dentry *dentry);
diff --git a/frontends/sfe/ecm_sfe_non_ported_ipv4.c b/frontends/sfe/ecm_sfe_non_ported_ipv4.c
index 83d52b5..0b4dbbf 100644
--- a/frontends/sfe/ecm_sfe_non_ported_ipv4.c
+++ b/frontends/sfe/ecm_sfe_non_ported_ipv4.c
@@ -535,7 +535,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -574,7 +574,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, from_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -702,7 +702,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -741,7 +741,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, to_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -1882,7 +1882,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -1892,7 +1892,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -1912,7 +1912,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -1924,7 +1924,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -1959,9 +1959,9 @@
 		 */
 		DEBUG_TRACE("%p: Create the 'from NAT' interface heirarchy list\n", nci);
 		if ((protocol == IPPROTO_IPV6) || (protocol == IPPROTO_ESP)) {
-			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL);
+			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL, skb);
 		} else {
-			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL);
+			from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev, src_node_addr_nat, dest_node_addr_nat, NULL, skb);
 		}
 
 		if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
@@ -1977,7 +1977,7 @@
 		ecm_db_connection_from_nat_interfaces_reset(nci, from_nat_list, from_nat_list_first);
 
 		DEBUG_TRACE("%p: Create source nat node\n", nci);
-		src_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat);
+		src_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(from_nat_list, from_nat_list_first);
 		if (!src_nat_ni) {
 			ecm_db_mapping_deref(dest_mi);
@@ -2004,7 +2004,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to NAT' interface heirarchy list\n", nci);
-		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, NULL);
+		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, NULL, skb);
 		if (to_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_nat_mi);
 			ecm_db_node_deref(src_nat_ni);
@@ -2020,7 +2020,7 @@
 		ecm_db_connection_to_nat_interfaces_reset(nci, to_nat_list, to_nat_list_first);
 
 		DEBUG_TRACE("%p: Create dest nat node\n", nci);
-		dest_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat);
+		dest_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(to_nat_list, to_nat_list_first);
 		if (!dest_nat_ni) {
 			ecm_db_mapping_deref(src_nat_mi);
@@ -2180,7 +2180,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_sfe_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, NULL);
+		ecm_sfe_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, NULL, skb);
 	}
 
 	/*
diff --git a/frontends/sfe/ecm_sfe_non_ported_ipv6.c b/frontends/sfe/ecm_sfe_non_ported_ipv6.c
index d0380ee..7efb4f0 100644
--- a/frontends/sfe/ecm_sfe_non_ported_ipv6.c
+++ b/frontends/sfe/ecm_sfe_non_ported_ipv6.c
@@ -471,7 +471,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -511,7 +511,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, from_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -639,7 +639,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -678,7 +678,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", nnpci, to_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -1760,7 +1760,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -1770,7 +1770,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -1790,7 +1790,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -1802,7 +1802,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -1943,7 +1943,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_sfe_ipv6_connection_regenerate(ci, sender, out_dev, in_dev);
+		ecm_sfe_ipv6_connection_regenerate(ci, sender, out_dev, in_dev, skb);
 	}
 
 	/*
diff --git a/frontends/sfe/ecm_sfe_ported_ipv4.c b/frontends/sfe/ecm_sfe_ported_ipv4.c
index 7bde29c..827726c 100644
--- a/frontends/sfe/ecm_sfe_ported_ipv4.c
+++ b/frontends/sfe/ecm_sfe_ported_ipv4.c
@@ -466,7 +466,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -505,7 +505,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, from_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -633,7 +633,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -672,7 +672,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, to_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -2039,7 +2039,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 4, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, layer4hdr, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -2049,7 +2049,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -2069,7 +2069,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 4, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, layer4hdr, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -2081,7 +2081,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -2111,7 +2111,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from NAT' interface heirarchy list\n", nci);
-		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr);
+		from_nat_list_first = ecm_interface_heirarchy_construct(feci, from_nat_list, ip_dest_addr, ip_src_addr_nat, 4, protocol, in_dev_nat, is_routed, in_dev_nat, src_node_addr_nat, dest_node_addr_nat, layer4hdr, skb);
 		if (from_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(dest_mi);
 			ecm_db_node_deref(dest_ni);
@@ -2125,7 +2125,7 @@
 		ecm_db_connection_from_nat_interfaces_reset(nci, from_nat_list, from_nat_list_first);
 
 		DEBUG_TRACE("%p: Create source nat node\n", nci);
-		src_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat);
+		src_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, in_dev_nat, ip_src_addr_nat, from_nat_list, from_nat_list_first, src_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(from_nat_list, from_nat_list_first);
 		if (!src_nat_ni) {
 			ecm_db_mapping_deref(dest_mi);
@@ -2152,7 +2152,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to NAT' interface heirarchy list\n", nci);
-		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr);
+		to_nat_list_first = ecm_interface_heirarchy_construct(feci, to_nat_list, ip_src_addr, ip_dest_addr_nat, 4, protocol, out_dev_nat, is_routed, in_dev, dest_node_addr_nat, src_node_addr_nat, layer4hdr, skb);
 		if (to_nat_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_nat_mi);
 			ecm_db_node_deref(src_nat_ni);
@@ -2168,7 +2168,7 @@
 		ecm_db_connection_to_nat_interfaces_reset(nci, to_nat_list, to_nat_list_first);
 
 		DEBUG_TRACE("%p: Create dest nat node\n", nci);
-		dest_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat);
+		dest_nat_ni = ecm_sfe_ipv4_node_establish_and_ref(feci, out_dev_nat, ip_dest_addr_nat, to_nat_list, to_nat_list_first, dest_node_addr_nat, skb);
 		ecm_db_connection_interfaces_deref(to_nat_list, to_nat_list_first);
 		if (!dest_nat_ni) {
 			ecm_db_mapping_deref(src_nat_mi);
@@ -2328,7 +2328,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_sfe_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, layer4hdr);
+		ecm_sfe_ipv4_connection_regenerate(ci, sender, out_dev, out_dev_nat, in_dev, in_dev_nat, layer4hdr, skb);
 	}
 
 	/*
diff --git a/frontends/sfe/ecm_sfe_ported_ipv6.c b/frontends/sfe/ecm_sfe_ported_ipv6.c
index 3c51777..4712c0c 100644
--- a/frontends/sfe/ecm_sfe_ported_ipv6.c
+++ b/frontends/sfe/ecm_sfe_ported_ipv6.c
@@ -471,7 +471,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -510,7 +510,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, from_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -638,7 +638,7 @@
 		 * Conflicting information may cause accel to be unsupported.
 		 */
 		switch (ii_type) {
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			struct ecm_db_interface_info_pppoe pppoe_info;
 #endif
 #ifdef ECM_INTERFACE_VLAN_ENABLE
@@ -677,7 +677,7 @@
 			DEBUG_TRACE("%p: Ethernet - mac: %pM\n", npci, to_sfe_iface_address);
 			break;
 		case ECM_DB_IFACE_TYPE_PPPOE:
-#ifdef ECM_INTERFACE_PPP_ENABLE
+#ifdef ECM_INTERFACE_PPPOE_ENABLE
 			/*
 			 * More than one PPPoE in the list is not valid!
 			 */
@@ -1946,7 +1946,7 @@
 		 * GGG TODO The empty list checks should not be needed, mapping_establish_and_ref() should fail out if there is no list anyway.
 		 */
 		DEBUG_TRACE("%p: Create the 'from' interface heirarchy list\n", nci);
-		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL);
+		from_list_first = ecm_interface_heirarchy_construct(feci, from_list, ip_dest_addr, ip_src_addr, 6, protocol, in_dev, is_routed, in_dev, src_node_addr, dest_node_addr, NULL, skb);
 		if (from_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			feci->deref(feci);
 			ecm_db_connection_deref(nci);
@@ -1956,7 +1956,7 @@
 		ecm_db_connection_from_interfaces_reset(nci, from_list, from_list_first);
 
 		DEBUG_TRACE("%p: Create source node\n", nci);
-		src_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr);
+		src_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, in_dev, ip_src_addr, from_list, from_list_first, src_node_addr, skb);
 		ecm_db_connection_interfaces_deref(from_list, from_list_first);
 		if (!src_ni) {
 			feci->deref(feci);
@@ -1976,7 +1976,7 @@
 		}
 
 		DEBUG_TRACE("%p: Create the 'to' interface heirarchy list\n", nci);
-		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL);
+		to_list_first = ecm_interface_heirarchy_construct(feci, to_list, ip_src_addr, ip_dest_addr, 6, protocol, out_dev, is_routed, in_dev, dest_node_addr, src_node_addr, NULL, skb);
 		if (to_list_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
 			ecm_db_mapping_deref(src_mi);
 			ecm_db_node_deref(src_ni);
@@ -1988,7 +1988,7 @@
 		ecm_db_connection_to_interfaces_reset(nci, to_list, to_list_first);
 
 		DEBUG_TRACE("%p: Create dest node\n", nci);
-		dest_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr);
+		dest_ni = ecm_sfe_ipv6_node_establish_and_ref(feci, out_dev, ip_dest_addr, to_list, to_list_first, dest_node_addr, skb);
 		ecm_db_connection_interfaces_deref(to_list, to_list_first);
 		if (!dest_ni) {
 			ecm_db_mapping_deref(src_mi);
@@ -2129,7 +2129,7 @@
 	 * Do we need to action generation change?
 	 */
 	if (unlikely(ecm_db_connection_regeneration_required_check(ci))) {
-		ecm_sfe_ipv6_connection_regenerate(ci, sender, out_dev, in_dev);
+		ecm_sfe_ipv6_connection_regenerate(ci, sender, out_dev, in_dev, skb);
 	}
 
 	/*