Project import generated by Copybara.

GitOrigin-RevId: 5a127c04ece96433b9596710e7acd87aabffda74
diff --git a/0001-Revert-SFE-ESP-changes.patch b/0001-Revert-SFE-ESP-changes.patch
new file mode 100644
index 0000000..d824011
--- /dev/null
+++ b/0001-Revert-SFE-ESP-changes.patch
@@ -0,0 +1,876 @@
+From 466a71a2b97c575ebc0cab4e2af94b00e83c2218 Mon Sep 17 00:00:00 2001
+From: Siva Eluri <eluris@google.com>
+Date: Fri, 3 Nov 2023 12:05:09 -0700
+Subject: [PATCH] Revert SFE ESP changes
+
+Change-Id: Ib5816fc4cc80ac8d1b6219d35871298c7bd5b409
+---
+ qca-nss-sfe/Makefile       |   4 +-
+ qca-nss-sfe/sfe.c          |   6 -
+ qca-nss-sfe/sfe_ipv4.c     |  31 +---
+ qca-nss-sfe/sfe_ipv4.h     |   4 -
+ qca-nss-sfe/sfe_ipv4_esp.c | 295 -------------------------------------
+ qca-nss-sfe/sfe_ipv4_esp.h |  21 ---
+ qca-nss-sfe/sfe_ipv6.c     |  29 +---
+ qca-nss-sfe/sfe_ipv6.h     |   4 -
+ qca-nss-sfe/sfe_ipv6_esp.c | 275 ----------------------------------
+ qca-nss-sfe/sfe_ipv6_esp.h |  21 ---
+ 10 files changed, 5 insertions(+), 685 deletions(-)
+ delete mode 100644 qca-nss-sfe/sfe_ipv4_esp.c
+ delete mode 100644 qca-nss-sfe/sfe_ipv4_esp.h
+ delete mode 100644 qca-nss-sfe/sfe_ipv6_esp.c
+ delete mode 100644 qca-nss-sfe/sfe_ipv6_esp.h
+
+diff --git a/qca-nss-sfe/Makefile b/qca-nss-sfe/Makefile
+index 6ac42d3..d52146c 100644
+--- a/qca-nss-sfe/Makefile
++++ b/qca-nss-sfe/Makefile
+@@ -5,8 +5,8 @@
+ KERNELVERSION := $(word 1, $(subst ., ,$(KERNELVERSION))).$(word 2, $(subst ., ,$(KERNELVERSION)))
+ 
+ SFE_BASE_OBJS := sfe.o sfe_init.o
+-SFE_IPV4_OBJS := sfe_ipv4.o sfe_ipv4_udp.o sfe_ipv4_tcp.o sfe_ipv4_icmp.o sfe_ipv4_esp.o
+-SFE_IPV6_OBJS := sfe_ipv6.o sfe_ipv6_udp.o sfe_ipv6_tcp.o sfe_ipv6_icmp.o sfe_ipv6_tunipip6.o sfe_ipv6_esp.o
++SFE_IPV4_OBJS := sfe_ipv4.o sfe_ipv4_udp.o sfe_ipv4_tcp.o sfe_ipv4_icmp.o
++SFE_IPV6_OBJS := sfe_ipv6.o sfe_ipv6_udp.o sfe_ipv6_tcp.o sfe_ipv6_icmp.o sfe_ipv6_tunipip6.o
+ SFE_PPPOE_OBJS := sfe_pppoe.o
+ 
+ 
+diff --git a/qca-nss-sfe/sfe.c b/qca-nss-sfe/sfe.c
+index 8bc387c..b352e9a 100644
+--- a/qca-nss-sfe/sfe.c
++++ b/qca-nss-sfe/sfe.c
+@@ -680,9 +680,6 @@ sfe_tx_status_t sfe_create_ipv4_rule_msg(struct sfe_ctx_instance_internal *sfe_c
+ 	case IPPROTO_GRE:
+ 		break;
+ 
+-	case IPPROTO_ESP:
+-		break;
+-
+ 	default:
+ 		ret = SFE_CMN_RESPONSE_EMSG;
+ 		sfe_incr_exceptions(SFE_EXCEPTION_PROTOCOL_NOT_SUPPORT);
+@@ -1051,9 +1048,6 @@ sfe_tx_status_t sfe_create_ipv6_rule_msg(struct sfe_ctx_instance_internal *sfe_c
+ 	case IPPROTO_GRE:
+ 		break;
+ 
+-	case IPPROTO_ESP:
+-		break;
+-
+ 	default:
+ 		ret = SFE_CMN_RESPONSE_EMSG;
+ 		sfe_incr_exceptions(SFE_EXCEPTION_PROTOCOL_NOT_SUPPORT);
+diff --git a/qca-nss-sfe/sfe_ipv4.c b/qca-nss-sfe/sfe_ipv4.c
+index 48eec72..aeb9a42 100644
+--- a/qca-nss-sfe/sfe_ipv4.c
++++ b/qca-nss-sfe/sfe_ipv4.c
+@@ -45,7 +45,6 @@
+ #include "sfe_ipv4_icmp.h"
+ #include "sfe_pppoe.h"
+ #include "sfe_ipv4_gre.h"
+-#include "sfe_ipv4_esp.h"
+ 
+ static char *sfe_ipv4_exception_events_string[SFE_IPV4_EXCEPTION_EVENT_LAST] = {
+ 	"UDP_HEADER_INCOMPLETE",
+@@ -96,10 +95,6 @@ static char *sfe_ipv4_exception_events_string[SFE_IPV4_EXCEPTION_EVENT_LAST] = {
+ 	"GRE_IP_OPTIONS_OR_INITIAL_FRAGMENT",
+ 	"GRE_SMALL_TTL",
+ 	"GRE_NEEDS_FRAGMENTATION",
+-	"ESP_NO_CONNECTION",
+-	"ESP_IP_OPTIONS_OR_INITIAL_FRAGMENT",
+-	"ESP_NEEDS_FRAGMENTATION",
+-	"ESP_SMALL_TTL"
+ };
+ 
+ static struct sfe_ipv4 __si;
+@@ -876,10 +871,6 @@ int sfe_ipv4_recv(struct net_device *dev, struct sk_buff *skb, struct sfe_l2_inf
+ 		return sfe_ipv4_recv_tcp(si, skb, dev, len, iph, ihl, sync_on_find, l2_info);
+ 	}
+ 
+-	if (IPPROTO_ESP == protocol) {
+-		return sfe_ipv4_recv_esp(si, skb, dev, len, iph, ihl, sync_on_find, tun_outer);
+-	}
+-
+ 	if (IPPROTO_ICMP == protocol) {
+ 		return sfe_ipv4_recv_icmp(si, skb, dev, len, iph, ihl);
+ 	}
+@@ -1279,8 +1270,7 @@ int sfe_ipv4_create_rule(struct sfe_ipv4_rule_create_msg *msg)
+ 		}
+ 	}
+ 
+-	if (((IPPROTO_GRE == tuple->protocol) || (IPPROTO_ESP == tuple->protocol)) &&
+-					!sfe_ipv4_is_local_ip(si, original_cm->match_dest_ip)) {
++	if ((IPPROTO_GRE == tuple->protocol) && !sfe_ipv4_is_local_ip(si, original_cm->match_dest_ip)) {
+ 		original_cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_PASSTHROUGH;
+ 	}
+ 
+@@ -1460,8 +1450,7 @@ int sfe_ipv4_create_rule(struct sfe_ipv4_rule_create_msg *msg)
+ 		reply_cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_FAST_XMIT_DEV_ADMISSION;
+ 	}
+ 
+-	if (((IPPROTO_GRE == tuple->protocol) || (IPPROTO_ESP == tuple->protocol)) &&
+-					!sfe_ipv4_is_local_ip(si, reply_cm->match_dest_ip)) {
++	if ((IPPROTO_GRE == tuple->protocol) && !sfe_ipv4_is_local_ip(si, reply_cm->match_dest_ip)) {
+ 		reply_cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_PASSTHROUGH;
+ 	}
+ 
+@@ -1571,22 +1560,6 @@ int sfe_ipv4_create_rule(struct sfe_ipv4_rule_create_msg *msg)
+ 	}
+ #endif
+ 
+-	if ((IPPROTO_ESP == tuple->protocol) && !(reply_cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PASSTHROUGH)) {
+-		rcu_read_lock();
+-		reply_cm->proto = rcu_dereference(inet_protos[IPPROTO_ESP]);
+-		rcu_read_unlock();
+-
+-		if (unlikely(!reply_cm->proto)) {
+-			kfree(reply_cm);
+-			kfree(original_cm);
+-			kfree(c);
+-			dev_put(src_dev);
+-			dev_put(dest_dev);
+-			DEBUG_WARN("sfe: ESP proto handler is not registered\n");
+-			return -EPERM;
+-		}
+-	}
+-
+ #ifdef CONFIG_NF_FLOW_COOKIE
+ 	reply_cm->flow_cookie = 0;
+ #endif
+diff --git a/qca-nss-sfe/sfe_ipv4.h b/qca-nss-sfe/sfe_ipv4.h
+index fcbc09b..4e8169b 100644
+--- a/qca-nss-sfe/sfe_ipv4.h
++++ b/qca-nss-sfe/sfe_ipv4.h
+@@ -288,10 +288,6 @@ enum sfe_ipv4_exception_events {
+ 	SFE_IPV4_EXCEPTION_EVENT_GRE_IP_OPTIONS_OR_INITIAL_FRAGMENT,
+ 	SFE_IPV4_EXCEPTION_EVENT_GRE_SMALL_TTL,
+ 	SFE_IPV4_EXCEPTION_EVENT_GRE_NEEDS_FRAGMENTATION,
+-	SFE_IPV4_EXCEPTION_EVENT_ESP_NO_CONNECTION,
+-	SFE_IPV4_EXCEPTION_EVENT_ESP_IP_OPTIONS_OR_INITIAL_FRAGMENT,
+-	SFE_IPV4_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION,
+-	SFE_IPV4_EXCEPTION_EVENT_ESP_SMALL_TTL,
+ 	SFE_IPV4_EXCEPTION_EVENT_LAST
+ };
+ 
+diff --git a/qca-nss-sfe/sfe_ipv4_esp.c b/qca-nss-sfe/sfe_ipv4_esp.c
+deleted file mode 100644
+index f0b4941..0000000
+--- a/qca-nss-sfe/sfe_ipv4_esp.c
++++ /dev/null
+@@ -1,295 +0,0 @@
+-/*
+- * sfe_ipv4_esp.c
+- *	Shortcut forwarding engine - IPv4 ESP implementation
+- *
+- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/skbuff.h>
+-#include <net/protocol.h>
+-#include <net/ip.h>
+-#include <linux/etherdevice.h>
+-#include <linux/lockdep.h>
+-
+-#include "sfe_debug.h"
+-#include "sfe_api.h"
+-#include "sfe.h"
+-#include "sfe_flow_cookie.h"
+-#include "sfe_ipv4.h"
+-#include "sfe_ipv4_esp.h"
+-
+-/*
+- * sfe_ipv4_recv_esp()
+- *	Handle ESP packet receives and forwarding
+- */
+-int sfe_ipv4_recv_esp(struct sfe_ipv4 *si, struct sk_buff *skb, struct net_device *dev,
+-				unsigned int len, struct iphdr *iph, unsigned int ihl,
+-				bool sync_on_find, bool tun_outer)
+-{
+-	struct sfe_ipv4_connection_match *cm;
+-	struct net_device *xmit_dev;
+-	struct net_protocol *ipprot;
+-	netdev_features_t features;
+-	bool passthrough;
+-	bool bridge_flow;
+-	bool fast_xmit;
+-	bool hw_csum;
+-	__be32 src_ip;
+-	__be32 dest_ip;
+-	bool ret;
+-	u8 ttl;
+-
+-	/*
+-	 * Read the IP address from the iphdr, and set the src/dst ports to 0.
+-	 */
+-	src_ip = iph->saddr;
+-	dest_ip = iph->daddr;
+-	rcu_read_lock();
+-
+-	/*
+-	 * Look for a connection match.
+-	 */
+-#ifdef CONFIG_NF_FLOW_COOKIE
+-	cm = si->sfe_flow_cookie_table[skb->flow_cookie & SFE_FLOW_COOKIE_MASK].match;
+-	if (unlikely(!cm)) {
+-		cm = sfe_ipv4_find_ipv4_connection_match_rcu(si, dev, IPPROTO_ESP, src_ip, 0, dest_ip, 0);
+-	}
+-#else
+-	cm = sfe_ipv4_find_connection_match_rcu(si, dev, IPPROTO_ESP, src_ip, 0, dest_ip, 0);
+-#endif
+-	if (unlikely(!cm)) {
+-		rcu_read_unlock();
+-		sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_ESP_NO_CONNECTION);
+-		DEBUG_TRACE("no connection found for esp packet\n");
+-		return 0;
+-	}
+-
+-	/*
+-	 * Source interface validate.
+-	 */
+-	if (unlikely((cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_SRC_INTERFACE_CHECK) && (cm->match_dev != dev))) {
+-		struct sfe_ipv4_connection *c = cm->connection;
+-		int ret;
+-
+-		spin_lock_bh(&si->lock);
+-		ret = sfe_ipv4_remove_connection(si, c);
+-		spin_unlock_bh(&si->lock);
+-
+-		if (ret) {
+-			sfe_ipv4_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
+-		}
+-		rcu_read_unlock();
+-		sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_INVALID_SRC_IFACE);
+-		DEBUG_TRACE("flush on wrong source interface check failure\n");
+-		return 0;
+-	}
+-
+-	passthrough = cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PASSTHROUGH;
+-	bridge_flow = !!(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_BRIDGE_FLOW);
+-
+-	/*
+-	 * If our packet has been marked as "sync on find" we can't actually
+-	 * forward it in the fast path, but now that we've found an associated
+-	 * connection we need sync its status before exception it to slow path unless
+-	 * it is passthrough (packets not directed to DUT) packet.
+-	 * TODO: revisit to ensure that pass through traffic is not bypassing firewall for fragmented cases
+-	 */
+-	if (unlikely(sync_on_find) && !passthrough) {
+-		sfe_ipv4_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
+-		rcu_read_unlock();
+-		sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_ESP_IP_OPTIONS_OR_INITIAL_FRAGMENT);
+-		DEBUG_TRACE("%px: sfe: sync on find\n", cm);
+-		return 0;
+-	}
+-
+-	/*
+-	 * Check if skb was cloned. If it was, unshare it.
+-	 */
+-	if (unlikely(skb_cloned(skb))) {
+-		DEBUG_TRACE("%px: skb is a cloned skb\n", skb);
+-		skb = skb_unshare(skb, GFP_ATOMIC);
+-		if (!skb) {
+-			DEBUG_WARN("Failed to unshare the cloned skb\n");
+-			rcu_read_unlock();
+-			return 0;
+-		}
+-
+-		/*
+-		 * Update the iphdr pointer with the unshared skb's data area.
+-		 */
+-		iph = (struct iphdr *)skb->data;
+-	}
+-
+-	/*
+-	 * Enable HW csum if rx checksum is verified and xmit interface is CSUM offload capable.
+-	 */
+-	hw_csum = !!(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_CSUM_OFFLOAD) && (skb->ip_summed == CHECKSUM_UNNECESSARY);
+-
+-	/*
+-	 * proto decap packet.
+-	 *	Invoke the inet_protocol handler for delivery of the packet.
+-	 */
+-	ipprot = rcu_dereference(cm->proto);
+-	if (likely(ipprot)) {
+-		skb_reset_network_header(skb);
+-		skb_pull(skb, ihl);
+-		skb_reset_transport_header(skb);
+-		xmit_dev = cm->xmit_dev;
+-		skb->dev = xmit_dev;
+-
+-		ret = ipprot->handler(skb);
+-		if (ret) {
+-			rcu_read_unlock();
+-			this_cpu_inc(si->stats_pcpu->packets_not_forwarded64);
+-			DEBUG_TRACE("ESP handler returned error %u\n", ret);
+-			return 0;
+-		}
+-
+-		/*
+-		 * Update traffic stats.
+-		 */
+-		atomic_inc(&cm->rx_packet_count);
+-		atomic_add(len, &cm->rx_byte_count);
+-
+-		rcu_read_unlock();
+-		this_cpu_inc(si->stats_pcpu->packets_forwarded64);
+-		return 1;
+-	}
+-
+-	/*
+-	 * esp passthrough / ip local out scenarios.
+-	 */
+-	/*
+-	 * If our packet is larger than the MTU of the transmit interface then
+-	 * we can't forward it easily.
+-	 */
+-	if (unlikely(len > cm->xmit_dev_mtu)) {
+-		sfe_ipv4_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
+-		rcu_read_unlock();
+-		sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION);
+-		DEBUG_TRACE("%px: sfe: larger than MTU\n", cm);
+-		return 0;
+-	}
+-
+-	/*
+-	 * need to ensure that TTL is >=2.
+-	 */
+-	ttl = iph->ttl;
+-	if (!bridge_flow && (ttl < 2) && passthrough) {
+-		sfe_ipv4_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
+-		rcu_read_unlock();
+-
+-		DEBUG_TRACE("%px: sfe: TTL too low\n", skb);
+-		sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_ESP_SMALL_TTL);
+-		return 0;
+-	}
+-
+-	/*
+-	 * decrement TTL by 1.
+-	 */
+-	iph->ttl = (ttl - (u8)(!bridge_flow && !tun_outer));
+-
+-	/*
+-	 * Update DSCP
+-	 */
+-	if (unlikely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_DSCP_REMARK)) {
+-		iph->tos = (iph->tos & SFE_IPV4_DSCP_MASK) | cm->dscp;
+-	}
+-
+-	/*
+-	 * Replace the IP checksum.
+-	 */
+-	if (likely(hw_csum)) {
+-		skb->ip_summed = CHECKSUM_PARTIAL;
+-	} else {
+-		iph->check = sfe_ipv4_gen_ip_csum(iph);
+-	}
+-
+-	/*
+-	 * Update traffic stats.
+-	 */
+-	atomic_inc(&cm->rx_packet_count);
+-	atomic_add(len, &cm->rx_byte_count);
+-
+-	xmit_dev = cm->xmit_dev;
+-	skb->dev = xmit_dev;
+-
+-	/*
+-	 * write the layer - 2 header.
+-	 */
+-	if (likely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_WRITE_L2_HDR)) {
+-		if (unlikely(!(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR))) {
+-			dev_hard_header(skb, xmit_dev, ETH_P_IP, cm->xmit_dest_mac, cm->xmit_src_mac, len);
+-		} else {
+-			/*
+-			 * For the simple case we write this really fast.
+-			 */
+-			struct ethhdr *eth = (struct ethhdr *)__skb_push(skb, ETH_HLEN);
+-			eth->h_proto = htons(ETH_P_IP);
+-			ether_addr_copy((u8 *)eth->h_dest, (u8 *)cm->xmit_dest_mac);
+-			ether_addr_copy((u8 *)eth->h_source, (u8 *)cm->xmit_src_mac);
+-		}
+-	}
+-
+-	/*
+-	 * Update priority of skb
+-	 */
+-	if (unlikely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_PRIORITY_REMARK)) {
+-		skb->priority = cm->priority;
+-	}
+-
+-	/*
+-	 * Mark outgoing packet.
+-	 */
+-	if (unlikely(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_MARK)) {
+-		skb->mark = cm->mark;
+-	}
+-
+-	/*
+-	 * For the first packets, check if it could got fast xmit.
+-	 */
+-	if (unlikely(!(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_FAST_XMIT_FLOW_CHECKED)
+-				&& (cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_FAST_XMIT_DEV_ADMISSION))){
+-		cm->features = netif_skb_features(skb);
+-		if (likely(sfe_fast_xmit_check(skb, cm->features))) {
+-			cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_FAST_XMIT;
+-		}
+-		cm->flags |= SFE_IPV4_CONNECTION_MATCH_FLAG_FAST_XMIT_FLOW_CHECKED;
+-	}
+-
+-	features = cm->features;
+-	fast_xmit = !!(cm->flags & SFE_IPV4_CONNECTION_MATCH_FLAG_FAST_XMIT);
+-
+-	rcu_read_unlock();
+-	this_cpu_inc(si->stats_pcpu->packets_forwarded64);
+-	prefetch(skb_shinfo(skb));
+-
+-	/*
+-	 * We do per packet condition check before we could fast xmit the
+-	 * packet.
+-	 */
+-	if (likely(fast_xmit && dev_fast_xmit(skb, xmit_dev, features))) {
+-		this_cpu_inc(si->stats_pcpu->packets_fast_xmited64);
+-		return 1;
+-	}
+-
+-	/*
+-	 * Mark that this packet has been fast forwarded.
+-	 */
+-	skb->fast_forwarded = 1;
+-
+-	dev_queue_xmit(skb);
+-	return 1;
+-}
+diff --git a/qca-nss-sfe/sfe_ipv4_esp.h b/qca-nss-sfe/sfe_ipv4_esp.h
+deleted file mode 100644
+index f889605..0000000
+--- a/qca-nss-sfe/sfe_ipv4_esp.h
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * sfe_ipv4_esp.h
+- *	Shortcut forwarding engine - IPv4 ESP header file
+- *
+- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-int sfe_ipv4_recv_esp(struct sfe_ipv4 *si, struct sk_buff *skb, struct net_device *dev, unsigned int len,
+-			struct iphdr *iph, unsigned int ihl, bool sync_on_find, bool tun_outer);
+diff --git a/qca-nss-sfe/sfe_ipv6.c b/qca-nss-sfe/sfe_ipv6.c
+index 9b9539f..372d9fb 100644
+--- a/qca-nss-sfe/sfe_ipv6.c
++++ b/qca-nss-sfe/sfe_ipv6.c
+@@ -46,7 +46,6 @@
+ #include "sfe_pppoe.h"
+ #include "sfe_ipv6_tunipip6.h"
+ #include "sfe_ipv6_gre.h"
+-#include "sfe_ipv6_esp.h"
+ 
+ #define sfe_ipv6_addr_copy(src, dest) memcpy((void *)(dest), (void *)(src), 16)
+ 
+@@ -105,10 +104,6 @@ static char *sfe_ipv6_exception_events_string[SFE_IPV6_EXCEPTION_EVENT_LAST] = {
+ 	"GRE_IP_OPTIONS_OR_INITIAL_FRAGMENT",
+ 	"GRE_SMALL_TTL",
+ 	"GRE_NEEDS_FRAGMENTATION",
+-	"ESP_NO_CONNECTION",
+-	"ESP_IP_OPTIONS_OR_INITIAL_FRAGMENT",
+-	"ESP_NEEDS_FRAGMENTATION",
+-	"ESP_SMALL_TTL"
+ };
+ 
+ static struct sfe_ipv6 __si6;
+@@ -868,10 +863,6 @@ int sfe_ipv6_recv(struct net_device *dev, struct sk_buff *skb, struct sfe_l2_inf
+ 		return sfe_ipv6_recv_tcp(si, skb, dev, len, iph, ihl, sync_on_find, l2_info);
+ 	}
+ 
+-	if (IPPROTO_ESP == next_hdr) {
+-		return sfe_ipv6_recv_esp(si, skb, dev, len, iph, ihl, sync_on_find, tun_outer);
+-	}
+-
+ 	if (IPPROTO_ICMPV6 == next_hdr) {
+ 		return sfe_ipv6_recv_icmp(si, skb, dev, len, iph, ihl);
+ 	}
+@@ -1547,7 +1538,7 @@ int sfe_ipv6_create_rule(struct sfe_ipv6_rule_create_msg *msg)
+ #ifdef SFE_GRE_TUN_ENABLE
+ 	if ((IPPROTO_GRE == tuple->protocol) && !(reply_cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PASSTHROUGH)) {
+ 		rcu_read_lock();
+-		reply_cm->proto = rcu_dereference(inet6_protos[IPPROTO_GRE]);
++		reply_cm->proto = rcu_dereference(inet6_protos[tuple->protocol]);
+ 		rcu_read_unlock();
+ 
+ 		if (unlikely(!reply_cm->proto)) {
+@@ -1564,24 +1555,6 @@ int sfe_ipv6_create_rule(struct sfe_ipv6_rule_create_msg *msg)
+ 	}
+ #endif
+ 
+-	if ((IPPROTO_ESP == tuple->protocol) && !(reply_cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PASSTHROUGH)) {
+-		rcu_read_lock();
+-		reply_cm->proto = rcu_dereference(inet6_protos[IPPROTO_ESP]);
+-		rcu_read_unlock();
+-
+-		if (unlikely(!reply_cm->proto)) {
+-			this_cpu_inc(si->stats_pcpu->connection_create_failures64);
+-			spin_unlock_bh(&si->lock);
+-			kfree(reply_cm);
+-			kfree(original_cm);
+-			kfree(c);
+-			dev_put(src_dev);
+-			dev_put(dest_dev);
+-			DEBUG_WARN("sfe: ESP proto handler is not registered\n");
+-			return -EPERM;
+-		}
+-	}
+-
+ 	/*
+ 	 * Decapsulation path have proto set.
+ 	 * This is used to differentiate de/encap, and call protocol specific handler.
+diff --git a/qca-nss-sfe/sfe_ipv6.h b/qca-nss-sfe/sfe_ipv6.h
+index f9a33f8..9c78f1c 100644
+--- a/qca-nss-sfe/sfe_ipv6.h
++++ b/qca-nss-sfe/sfe_ipv6.h
+@@ -307,10 +307,6 @@ enum sfe_ipv6_exception_events {
+ 	SFE_IPV6_EXCEPTION_EVENT_GRE_IP_OPTIONS_OR_INITIAL_FRAGMENT,
+ 	SFE_IPV6_EXCEPTION_EVENT_GRE_SMALL_TTL,
+ 	SFE_IPV6_EXCEPTION_EVENT_GRE_NEEDS_FRAGMENTATION,
+-	SFE_IPV6_EXCEPTION_EVENT_ESP_NO_CONNECTION,
+-	SFE_IPV6_EXCEPTION_EVENT_ESP_IP_OPTIONS_OR_INITIAL_FRAGMENT,
+-	SFE_IPV6_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION,
+-	SFE_IPV6_EXCEPTION_EVENT_ESP_SMALL_TTL,
+ 	SFE_IPV6_EXCEPTION_EVENT_LAST
+ };
+ 
+diff --git a/qca-nss-sfe/sfe_ipv6_esp.c b/qca-nss-sfe/sfe_ipv6_esp.c
+deleted file mode 100644
+index 7a152e8..0000000
+--- a/qca-nss-sfe/sfe_ipv6_esp.c
++++ /dev/null
+@@ -1,275 +0,0 @@
+-/*
+- * sfe_ipv6_esp.c
+- *	Shortcut forwarding engine - IPv6 ESP implementation
+- *
+- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/skbuff.h>
+-#include <net/protocol.h>
+-#include <net/ip6_checksum.h>
+-#include <linux/etherdevice.h>
+-#include <linux/version.h>
+-
+-#include "sfe_debug.h"
+-#include "sfe_api.h"
+-#include "sfe.h"
+-#include "sfe_flow_cookie.h"
+-#include "sfe_ipv6.h"
+-#include "sfe_ipv6_esp.h"
+-
+-/*
+- * sfe_ipv6_recv_esp()
+- *	Handle ESP packet receives and forwarding
+- */
+-int sfe_ipv6_recv_esp(struct sfe_ipv6 *si, struct sk_buff *skb, struct net_device *dev,
+-				unsigned int len, struct ipv6hdr *iph, unsigned int ihl,
+-				bool sync_on_find, bool tun_outer)
+-{
+-	struct sfe_ipv6_connection_match *cm;
+-	struct sfe_ipv6_addr *src_ip;
+-	struct sfe_ipv6_addr *dest_ip;
+-	struct net_device *xmit_dev;
+-	struct inet6_protocol *ipprot;
+-	netdev_features_t features;
+-	bool bridge_flow;
+-	bool passthrough;
+-	bool fast_xmit;
+-	bool ret;
+-
+-	/*
+-	 * Read the IP address from the iphdr, and set the src/dst ports to 0.
+-	 */
+-	src_ip = (struct sfe_ipv6_addr *)iph->saddr.s6_addr32;
+-	dest_ip = (struct sfe_ipv6_addr *)iph->daddr.s6_addr32;
+-	rcu_read_lock();
+-
+-	/*
+-	 * Look for a connection match.
+-	 */
+-#ifdef CONFIG_NF_FLOW_COOKIE
+-	cm = si->sfe_flow_cookie_table[skb->flow_cookie & SFE_FLOW_COOKIE_MASK].match;
+-	if (unlikely(!cm)) {
+-		cm = sfe_ipv6_find_connection_match_rcu(si, dev, IPPROTO_ESP, src_ip, 0, dest_ip, 0);
+-	}
+-#else
+-	cm = sfe_ipv6_find_connection_match_rcu(si, dev, IPPROTO_ESP, src_ip, 0, dest_ip, 0);
+-#endif
+-	if (unlikely(!cm)) {
+-		rcu_read_unlock();
+-		sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_ESP_NO_CONNECTION);
+-
+-		DEBUG_TRACE("no connection found for esp packet\n");
+-		return 0;
+-	}
+-
+-	/*
+-	 * Source interface validate.
+-	 */
+-	if (unlikely((cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_SRC_INTERFACE_CHECK) && (cm->match_dev != dev))) {
+-		struct sfe_ipv6_connection *c = cm->connection;
+-		int ret;
+-
+-		spin_lock_bh(&si->lock);
+-		ret = sfe_ipv6_remove_connection(si, c);
+-		spin_unlock_bh(&si->lock);
+-
+-		if (ret) {
+-			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
+-		}
+-		rcu_read_unlock();
+-		sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_INVALID_SRC_IFACE);
+-		DEBUG_TRACE("flush on wrong source interface check failure\n");
+-		return 0;
+-	}
+-
+-	passthrough = cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PASSTHROUGH;
+-	bridge_flow = !!(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_BRIDGE_FLOW);
+-
+-	/*
+-	 * If our packet has beern marked as "sync on find" we can't actually
+-	 * forward it in the fast path, but now that we've found an associated
+-	 * connection we need sync its status before exception it to slow path. unless
+-	 * it is passthrough packet.
+-	 * TODO: revisit to ensure that pass through traffic is not bypassing firewall for fragmented cases
+-	 */
+-	if (unlikely(sync_on_find) && !passthrough) {
+-		sfe_ipv6_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
+-		rcu_read_unlock();
+-
+-		sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_ESP_IP_OPTIONS_OR_INITIAL_FRAGMENT);
+-		DEBUG_TRACE("Sync on find\n");
+-		return 0;
+-	}
+-
+-	/*
+-	 * Check if skb was cloned. If it was, unshare it.
+-	 */
+-	if (unlikely(skb_cloned(skb))) {
+-		DEBUG_TRACE("%px: skb is a cloned skb\n", skb);
+-		skb = skb_unshare(skb, GFP_ATOMIC);
+-		if (!skb) {
+-			DEBUG_WARN("Failed to unshare the cloned skb\n");
+-			rcu_read_unlock();
+-			return 0;
+-		}
+-
+-		/*
+-		 * Update the iphdr pointer with the unshared skb's data area.
+-		 */
+-		iph = (struct ipv6hdr *)skb->data;
+-	}
+-
+-	/*
+-	 * proto decap packet.
+-	 *	Invoke the inet_protocol handler for delivery of the packet.
+-	 */
+-	ipprot = rcu_dereference(cm->proto);
+-	if (likely(ipprot)) {
+-		skb_reset_network_header(skb);
+-		skb_pull(skb, ihl);
+-		skb_reset_transport_header(skb);
+-		xmit_dev = cm->xmit_dev;
+-		skb->dev = xmit_dev;
+-
+-		ret = ipprot->handler(skb);
+-		if (ret) {
+-			rcu_read_unlock();
+-			this_cpu_inc(si->stats_pcpu->packets_not_forwarded64);
+-			DEBUG_TRACE("ESP handler returned error %u\n", ret);
+-			return 0;
+-		}
+-
+-		rcu_read_unlock();
+-		this_cpu_inc(si->stats_pcpu->packets_forwarded64);
+-		return 1;
+-	}
+-
+-	/*
+-	 * esp passthrough / ip local out scenarios
+-	 */
+-	/*
+-	 * If our packet is larger than the MTU of the transmit interface then
+-	 * we can't forward it easily.
+-	 */
+-	if (unlikely(len > cm->xmit_dev_mtu)) {
+-		sfe_ipv6_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
+-		rcu_read_unlock();
+-
+-		sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION);
+-		DEBUG_TRACE("Larger than MTU\n");
+-		return 0;
+-	}
+-
+-	/*
+-	 * need to ensure that TTL is >=2.
+-	 */
+-	if (!bridge_flow && (iph->hop_limit < 2) && passthrough) {
+-		sfe_ipv6_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
+-		rcu_read_unlock();
+-
+-		sfe_ipv6_exception_stats_inc(si, SFE_IPV6_EXCEPTION_EVENT_ESP_SMALL_TTL);
+-		DEBUG_TRACE("hop_limit too low\n");
+-		return 0;
+-	}
+-
+-	/*
+-	 * decrement TTL by 1.
+-	 */
+-	iph->hop_limit = iph->hop_limit - (u8)(!bridge_flow && !tun_outer);
+-
+-	/*
+-	 * Update DSCP
+-	 */
+-	if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK)) {
+-		sfe_ipv6_change_dsfield(iph, cm->dscp);
+-	}
+-
+-	/*
+-	 * Update traffic stats.
+-	 */
+-	atomic_inc(&cm->rx_packet_count);
+-	atomic_add(len, &cm->rx_byte_count);
+-
+-	xmit_dev = cm->xmit_dev;
+-	skb->dev = xmit_dev;
+-
+-	/*
+-	 * write the layer - 2 header.
+-	 */
+-	if (likely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_L2_HDR)) {
+-		if (unlikely(!(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR))) {
+-			dev_hard_header(skb, xmit_dev, ETH_P_IPV6, cm->xmit_dest_mac, cm->xmit_src_mac, len);
+-		} else {
+-			/*
+-			 * For the simple case we write this really fast.
+-			 */
+-			struct ethhdr *eth = (struct ethhdr *)__skb_push(skb, ETH_HLEN);
+-			eth->h_proto = htons(ETH_P_IPV6);
+-			ether_addr_copy((u8 *)eth->h_dest, (u8 *)cm->xmit_dest_mac);
+-			ether_addr_copy((u8 *)eth->h_source, (u8 *)cm->xmit_src_mac);
+-		}
+-	}
+-
+-	/*
+-	 * Update priority of skb.
+-	 */
+-	if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PRIORITY_REMARK)) {
+-		skb->priority = cm->priority;
+-	}
+-
+-	/*
+-	 * Mark outgoing packet.
+-	 */
+-	if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_MARK)) {
+-		skb->mark = cm->mark;
+-	}
+-
+-	/*
+-	 * For the first packets, check if it could got fast xmit.
+-	 */
+-	if (unlikely(!(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_FAST_XMIT_FLOW_CHECKED)
+-				&& (cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_FAST_XMIT_DEV_ADMISSION))){
+-		cm->features = netif_skb_features(skb);
+-		if (likely(sfe_fast_xmit_check(skb, cm->features))) {
+-			cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_FAST_XMIT;
+-		}
+-		cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_FAST_XMIT_FLOW_CHECKED;
+-	}
+-
+-	features = cm->features;
+-	fast_xmit = !!(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_FAST_XMIT);
+-
+-	rcu_read_unlock();
+-	this_cpu_inc(si->stats_pcpu->packets_forwarded64);
+-	prefetch(skb_shinfo(skb));
+-
+-	/*
+-	 * We do per packet condition check before we could fast xmit the
+-	 * packet.
+-	 */
+-	if (likely(fast_xmit && dev_fast_xmit(skb, xmit_dev, features))) {
+-		this_cpu_inc(si->stats_pcpu->packets_fast_xmited64);
+-		return 1;
+-	}
+-
+-	/*
+-	 * Mark that this packet has been fast forwarded.
+-	 */
+-	skb->fast_forwarded = 1;
+-
+-	dev_queue_xmit(skb);
+-	return 1;
+-}
+diff --git a/qca-nss-sfe/sfe_ipv6_esp.h b/qca-nss-sfe/sfe_ipv6_esp.h
+deleted file mode 100644
+index 2870670..0000000
+--- a/qca-nss-sfe/sfe_ipv6_esp.h
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * sfe_ipv6_esp.h
+- *	Shortcut forwarding engine - IPv6 ESP header file
+- *
+- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-int sfe_ipv6_recv_esp(struct sfe_ipv6 *si, struct sk_buff *skb, struct net_device *dev, unsigned int len,
+-			struct ipv6hdr *iph, unsigned int ihl, bool sync_on_find, bool tun_outer);
+-- 
+2.42.0.869.gea05f2083d-goog
+
diff --git a/build_scripts/build_all.sh b/build_scripts/build_all.sh
index 111d8c1..32edba4 100755
--- a/build_scripts/build_all.sh
+++ b/build_scripts/build_all.sh
@@ -4,11 +4,17 @@
 
 top_dir=$(readlink -e $(dirname $0)/../../)
 
-declare -A PRODUCT_LIST=([sirocco]="sirocco-p1 sirocco-b1 sirocco-b3 sirocco-b4")
+# Plan to support different brezza board:
+# brezza-p1: 2022/08
+# brezza-p2: 2022/10
+# brezza-b1: 2023/01
+# brezza-b3: 2023/04
+# brezza-b4: 2023/05
+declare -A PRODUCT_LIST=([sirocco]="sirocco-p1 sirocco-b1 sirocco-b3 sirocco-b4" [brezza]="brezza-p0 brezza-p1 brezza-p2 brezza-b1 brezza-b3 brezza-b4")
 
 function Help() {
   echo "Usage: $0  <eureka_workspace> <product/board> [optional build number] [other options]"
-  echo "  valid product : sirocco"
+  echo "  valid product : sirocco, brezza"
   echo "  available options: --venv_root=<venv_root>"
 }
 
@@ -134,6 +140,10 @@
   pushd ${top_dir}/sdk/qca-nss-ecm
   ./build.sh ${product} ${eureka_src_path}
   popd
+
+  pushd ${top_dir}/ta
+  ./build.sh ${product} ${eureka_src_path}
+  popd
 }
 
 #########################
diff --git a/nat46/build.sh b/nat46/build.sh
index 9fccc30..3299a75 100755
--- a/nat46/build.sh
+++ b/nat46/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-nss-clients/build.sh b/qca-nss-clients/build.sh
index 88fb760..e155439 100755
--- a/qca-nss-clients/build.sh
+++ b/qca-nss-clients/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-nss-dp/build.sh b/qca-nss-dp/build.sh
index 026f25b..04f359d 100755
--- a/qca-nss-dp/build.sh
+++ b/qca-nss-dp/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-nss-dp/nss_dp_main.c b/qca-nss-dp/nss_dp_main.c
index f9607de..dea8c05 100644
--- a/qca-nss-dp/nss_dp_main.c
+++ b/qca-nss-dp/nss_dp_main.c
@@ -809,6 +809,7 @@
 	uint8_t *maddr;
 	struct nss_dp_dev *dp_priv;
 	struct resource memres_devtree = {0};
+	uint32_t is_wan_interface;
 
 	dp_priv = netdev_priv(netdev);
 
@@ -817,13 +818,17 @@
 		return -EFAULT;
 	}
 
+        if (of_property_read_u32(np, "is_wan", &is_wan_interface)) {
+                pr_err("%s: error reading is_wan\n", np->name);
+                return -EFAULT;
+        }
+
 	/*
-	 * change interface 1 name to wan0
-	 * change interface 2 name to lan0
+	 * Name WAN/LAN interfaces as per hint from DTSI
 	 */
-	if (dp_priv->macid == 1) {
+	if (is_wan_interface) {
 		strcpy(netdev->name, "wan0");
-	} else if (dp_priv->macid == 2) {
+	} else {
 		strcpy(netdev->name, "lan0");
 	}
 
diff --git a/qca-nss-drv/build.sh b/qca-nss-drv/build.sh
index 9afc226..9677207 100755
--- a/qca-nss-drv/build.sh
+++ b/qca-nss-drv/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-nss-ecm/build.sh b/qca-nss-ecm/build.sh
index 452d82c..f1528d0 100755
--- a/qca-nss-ecm/build.sh
+++ b/qca-nss-ecm/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-nss-ecm/ecm_db/ecm_db_connection.c b/qca-nss-ecm/ecm_db/ecm_db_connection.c
index 717aa3a..054638e 100644
--- a/qca-nss-ecm/ecm_db/ecm_db_connection.c
+++ b/qca-nss-ecm/ecm_db/ecm_db_connection.c
@@ -406,45 +406,37 @@
 	DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", ci);
 
 	/*
+	 * Call the frontend's defunct callback function and handle the return values.
+	 */
+	ret = ci->defunct(ci->feci, &accel_mode);
+
+	/*
 	 * If connection's defunct timer is already removed from the groups,
 	 * this means that the connection is timed out and already in defunct process.
-	 * So, let's not continue in this defunct process.
+	 * So, we needn't destroy the connection any more.
 	 */
 	spin_lock_bh(&ecm_db_lock);
 	if (ci->defunct_timer.group == ECM_DB_TIMER_GROUPS_MAX) {
 		spin_unlock_bh(&ecm_db_lock);
 		return;
 	}
-	spin_unlock_bh(&ecm_db_lock);
-
-	/*
-	 * Call the frontend's defunct callback function and handle the return values.
-	 */
-	ret = ci->defunct(ci->feci, &accel_mode);
 
 	/*
 	 * If the defunct is success, first we should remove the timer and then release
-	 * the last reference. It is possible that while we are handling the defunct callback,
-	 * the timer was expired and removed from the list. So, we don't need to check the
-	 * return value of the timer removal function. Regardless of who removed the timer, we should
-	 * release the last reference.
+	 * the last reference.
+	 * If defunct fails and the connection state is in one of the fail states, we should remove the timer
+	 * and release the last reference.
+	 * the removal of timer will always be successful here, we needn't check the
+	 * return value.
 	 */
-	if (ret) {
-		ecm_db_timer_group_entry_remove(&ci->defunct_timer);
+	if (ret || ECM_FRONT_END_ACCELERATION_FAILED(accel_mode)) {
+		_ecm_db_timer_group_entry_remove(&ci->defunct_timer);
+		spin_unlock_bh(&ecm_db_lock);
 		ecm_db_connection_deref(ci);
 		return;
 	}
 
-	/*
-	 * If defunct fails and the connection state is in one of the fail states, we should remove the timer
-	 * and release the last reference. In this case we should check the timer removal function's return value
-	 * to make sure that it is removed by us.
-	 */
-	if (ECM_FRONT_END_ACCELERATION_FAILED(accel_mode)) {
-		if (ecm_db_timer_group_entry_remove(&ci->defunct_timer)) {
-			ecm_db_connection_deref(ci);
-		}
-	}
+	spin_unlock_bh(&ecm_db_lock);
 }
 EXPORT_SYMBOL(ecm_db_connection_make_defunct);
 
diff --git a/qca-nss-ecm/ecm_interface.c b/qca-nss-ecm/ecm_interface.c
index 7058f15..2bc862d 100644
--- a/qca-nss-ecm/ecm_interface.c
+++ b/qca-nss-ecm/ecm_interface.c
@@ -1,7 +1,7 @@
 /*
  **************************************************************************
  * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -2579,7 +2579,6 @@
 	case ECM_DB_IFACE_TYPE_GRE_TUN:
 	case ECM_DB_IFACE_TYPE_GRE_TAP:
 	case ECM_DB_IFACE_TYPE_VXLAN:
-	case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
 		if (src_dev) {
 			*mtu = src_dev->mtu;
 		} else {
@@ -3203,22 +3202,6 @@
 #endif
 		type_info.ipsec_tunnel.os_specific_ident = dev_interface_num;
 
-		/*
-		 * Override the MTU size in the decap direction in case of IPSec tunnel.
-		 * This will apply to IPsec->WAN rule.
-		 * TODO: Move this override to accelerate function.
-		 */
-		if (ip_hdr(skb)->version == IPVERSION) {
-			if ((ip_hdr(skb)->protocol == IPPROTO_ESP) ||
-			    ((ip_hdr(skb)->protocol == IPPROTO_UDP) &&
-			     (udp_hdr(skb)->dest == htons(4500)))) {
-				dev_mtu = ECM_DB_IFACE_MTU_MAX;
-			}
-		} else {
-			if (ipv6_hdr(skb)->nexthdr == IPPROTO_ESP) {
-				dev_mtu = ECM_DB_IFACE_MTU_MAX;
-			}
-		}
 
 		ii = ecm_interface_ipsec_tunnel_interface_establish(&type_info.ipsec_tunnel, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
 		if (ii) {
diff --git a/qca-nss-ecm/examples/ecm_sfe_l2.c b/qca-nss-ecm/examples/ecm_sfe_l2.c
index dd64653..b69df5a 100644
--- a/qca-nss-ecm/examples/ecm_sfe_l2.c
+++ b/qca-nss-ecm/examples/ecm_sfe_l2.c
@@ -155,7 +155,6 @@
 						   tuple->dest_addr, tuple->dest_port, tuple->protocol);
 		if (!rule) {
 			spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
-			pr_warn("No rule with this tuple\n");
 			goto done;
 		}
 		direction = rule->direction;
@@ -175,7 +174,6 @@
 
 		if (!rule) {
 			spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
-			pr_warn("No rule with this tuple\n");
 			goto done;
 		}
 		direction = rule->direction;
@@ -296,7 +294,7 @@
 	spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
 	kfree(rule);
 
-	pr_info("rule deleted\n");
+	pr_debug("rule deleted\n");
 	return true;
 }
 
@@ -312,7 +310,7 @@
 	rule = ecm_sfe_l2_policy_rule_find(ip_ver, sip_addr, sport, dip_addr, dport, protocol);
 	if (rule) {
 		if (rule->direction != direction) {
-			pr_info("Update direction of the rule from %d to %d\n", rule->direction, direction);
+			pr_debug("Update direction of the rule from %d to %d\n", rule->direction, direction);
 			rule->direction = direction;
 		}
 		spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
@@ -341,7 +339,7 @@
 	list_add(&rule->list, &ecm_sfe_l2_policy_rules);
 	spin_unlock_bh(&ecm_sfe_l2_policy_rules_lock);
 
-	pr_info("rule added\n");
+	pr_debug("rule added\n");
 	return true;
 }
 
@@ -388,13 +386,13 @@
 	 */
 	fields = cmd_buf;
 	while ((token = strsep(&fields, " "))) {
-		pr_info("\ntoken: %s\n", token);
+		pr_debug("\ntoken: %s\n", token);
 
 		option = strsep(&token, "=");
 		value = token;
 
-		pr_info("\t\toption: %s\n", option);
-		pr_info("\t\tvalue: %s\n", value);
+		pr_debug("\t\toption: %s\n", option);
+		pr_debug("\t\tvalue: %s\n", value);
 
 		if (!strcmp(option, "cmd")) {
 			if (sscanf(value, "%d", &cmd)) {
diff --git a/qca-nss-sfe/build.sh b/qca-nss-sfe/build.sh
index 2378401..09493c5 100755
--- a/qca-nss-sfe/build.sh
+++ b/qca-nss-sfe/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-nss-sfe/sfe_ipv4_udp.c b/qca-nss-sfe/sfe_ipv4_udp.c
index 4b15f7c..ec3b2e9 100644
--- a/qca-nss-sfe/sfe_ipv4_udp.c
+++ b/qca-nss-sfe/sfe_ipv4_udp.c
@@ -3,7 +3,7 @@
  *	Shortcut forwarding engine - IPv4 UDP implementation
  *
  * Copyright (c) 2013-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -263,7 +263,7 @@
 	 * If our packet is larger than the MTU of the transmit interface then
 	 * we can't forward it easily.
 	 */
-	if (unlikely(len > cm->xmit_dev_mtu)) {
+	if (unlikely((len > cm->xmit_dev_mtu) && (!cm->up))) {
 		sfe_ipv4_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
 		rcu_read_unlock();
 		sfe_ipv4_exception_stats_inc(si, SFE_IPV4_EXCEPTION_EVENT_UDP_NEEDS_FRAGMENTATION);
diff --git a/qca-nss-sfe/sfe_ipv6.c b/qca-nss-sfe/sfe_ipv6.c
index 9670c7e..5b610dd 100644
--- a/qca-nss-sfe/sfe_ipv6.c
+++ b/qca-nss-sfe/sfe_ipv6.c
@@ -3,7 +3,7 @@
  *	Shortcut forwarding engine - IPv6 support.
  *
  * Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1536,7 +1536,7 @@
 	reply_cm->top_interface_dev = NULL;
 
 #ifdef SFE_GRE_TUN_ENABLE
-	if (!(reply_cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PASSTHROUGH)) {
+	if ((IPPROTO_GRE == tuple->protocol) && !(reply_cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PASSTHROUGH)) {
 		rcu_read_lock();
 		reply_cm->proto = rcu_dereference(inet6_protos[tuple->protocol]);
 		rcu_read_unlock();
diff --git a/qca-nss-sfe/sfe_ipv6_udp.c b/qca-nss-sfe/sfe_ipv6_udp.c
index 445b43f..74802eb 100644
--- a/qca-nss-sfe/sfe_ipv6_udp.c
+++ b/qca-nss-sfe/sfe_ipv6_udp.c
@@ -3,7 +3,7 @@
  *	Shortcut forwarding engine file for IPv6 UDP
  *
  * Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -269,7 +269,7 @@
 	 * If our packet is larger than the MTU of the transmit interface then
 	 * we can't forward it easily.
 	 */
-	if (unlikely(len > cm->xmit_dev_mtu)) {
+	if (unlikely((len > cm->xmit_dev_mtu) && (!cm->up))) {
 		sfe_ipv6_sync_status(si, cm->connection, SFE_SYNC_REASON_STATS);
 		rcu_read_unlock();
 
diff --git a/qca-ovsmgr/build.sh b/qca-ovsmgr/build.sh
index 84df137..b6c19ef 100755
--- a/qca-ovsmgr/build.sh
+++ b/qca-ovsmgr/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-ssdk/build.sh b/qca-ssdk/build.sh
index c0d1b70..16a23b1 100755
--- a/qca-ssdk/build.sh
+++ b/qca-ssdk/build.sh
@@ -4,7 +4,7 @@
 set -o errtrace
 trap 'echo Fatal error: script $0 aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
 
-PRODUCT_LIST="sirocco"
+PRODUCT_LIST="sirocco brezza"
 
 NUM_JOBS=$(grep -c processor /proc/cpuinfo)
 
diff --git a/qca-ssdk/make/linux_opt.mk b/qca-ssdk/make/linux_opt.mk
index 81680f8..dde7d85 100755
--- a/qca-ssdk/make/linux_opt.mk
+++ b/qca-ssdk/make/linux_opt.mk
@@ -1,5 +1,5 @@
 MODULE_CFLAG :=
-LOCAL_CFLAGS :=
+LOCAL_CFLAGS := -fno-pic
 
 ifeq (TRUE, $(SWCONFIG))
   MODULE_CFLAG += -DIN_SWCONFIG
diff --git a/qca-ssdk/src/hsl/phy/qca808x.c b/qca-ssdk/src/hsl/phy/qca808x.c
index 4a6301a..ee16b6f 100755
--- a/qca-ssdk/src/hsl/phy/qca808x.c
+++ b/qca-ssdk/src/hsl/phy/qca808x.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2018-2019, 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all copies.
@@ -340,7 +341,7 @@
 
 static int qca808x_config_aneg(struct phy_device *phydev)
 {
-	a_uint32_t advertise = 0;
+	a_uint32_t advertise = 0, advertise_old = 0;
 	a_uint16_t phy_data = 0;
 	int err = 0;
 	a_uint32_t dev_id = 0, phy_id = 0;
@@ -380,8 +381,13 @@
 		if(!(advertise & ~(FAL_PHY_ADV_PAUSE | FAL_PHY_ADV_ASY_PAUSE))) {
 			return SW_BAD_VALUE;
 		}
-		err |= qca808x_phy_set_autoneg_adv(dev_id, phy_id, advertise);
-		err |= qca808x_phy_restart_autoneg(dev_id, phy_id);
+		err |= qca808x_phy_get_autoneg_adv(dev_id, phy_id, &advertise_old);
+
+		SSDK_DEBUG("advertise: 0x%x, advertise_old: 0x%x\n", advertise, advertise_old);
+		if(advertise != advertise_old) {
+			err |= qca808x_phy_set_autoneg_adv(dev_id, phy_id, advertise);
+			err |= qca808x_phy_restart_autoneg(dev_id, phy_id);
+		}
 	}
 
 	return err;
diff --git a/qca-ssdk/src/hsl/phy/qca808x_phy.c b/qca-ssdk/src/hsl/phy/qca808x_phy.c
index 43bb27a..bc109e6 100755
--- a/qca-ssdk/src/hsl/phy/qca808x_phy.c
+++ b/qca-ssdk/src/hsl/phy/qca808x_phy.c
@@ -630,8 +630,10 @@
 	rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL,
 			     phy_data | QCA808X_CTRL_SOFTWARE_RESET);
 	SW_RTN_ON_ERROR(rv);
+
 	/*the configure will lost when reset.*/
-	rv = qca808x_phy_ms_seed_enable(dev_id, phy_id, A_TRUE);
+	if (qca808x_phy_2500caps(dev_id, phy_id) == A_TRUE)
+		rv = qca808x_phy_ms_seed_enable(dev_id, phy_id, A_TRUE);
 
 	return rv;
 }
diff --git a/requirements3.in b/requirements3.in
index cf3c711..3289284 100644
--- a/requirements3.in
+++ b/requirements3.in
@@ -4,5 +4,6 @@
 kerberos==1.3.0
 pycrypto==2.6.1
 PyYAML==5.3
+scons==4.3.0
 servo==1
 sublime==0.1.0
diff --git a/requirements3.txt b/requirements3.txt
index 8c68261..bd60bda 100644
--- a/requirements3.txt
+++ b/requirements3.txt
@@ -1,5 +1,5 @@
 #
-# This file is autogenerated by pip-compile with python 3.9
+# This file is autogenerated by pip-compile with python 3.10
 # To update, run:
 #
 #    pip-compile --output-file=requirements3.txt requirements3.in
@@ -16,9 +16,14 @@
     # via -r requirements3.in
 pyyaml==5.3
     # via -r requirements3.in
+scons==4.3.0
+    # via -r requirements3.in
 servo==1
     # via -r requirements3.in
 sublime==0.1.0
     # via -r requirements3.in
 wand==0.4.4
     # via -r requirements3.in
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools