diff --git a/tests/TestSuite_vf_offload.py b/tests/TestSuite_vf_offload.py
index 5def34c1..ce1a6f13 100644
--- a/tests/TestSuite_vf_offload.py
+++ b/tests/TestSuite_vf_offload.py
@@ -258,8 +258,8 @@ class TestVfOffload(TestCase):
             p
             for p in packets
             if len(p.layers()) >= 3
-            and p.layers()[1] in {IP, IPv6}
-            and p.layers()[2] in {IP, IPv6, UDP, TCP, SCTP, GRE, MPLS}
+            and p.layers()[1] in {IP, IPv6, Dot1Q}
+            and p.layers()[2] in {IP, IPv6, Dot1Q, UDP, TCP, SCTP, GRE, MPLS}
             and Raw in p
         ]
 
@@ -400,6 +400,70 @@ class TestVfOffload(TestCase):
 
         self.verify(len(result) == 0, ",".join(list(result.values())))
 
+    def test_checksum_offload_vlan_enable(self):
+        """
+        Enable HW checksum offload.
+        Send packet with incorrect checksum,
+        can rx it and report the checksum error,
+        verify forwarded packets have correct checksum.
+        """
+        self.launch_testpmd(
+            dcf_flag=self.dcf_mode,
+            param="--portmask=%s " % (self.portMask) + "--enable-rx-cksum " + "",
+        )
+        self.vm0_testpmd.execute_cmd("set fwd csum")
+        self.vm0_testpmd.execute_cmd("csum mac-swap off 0", "testpmd>")
+        self.vm0_testpmd.execute_cmd("csum mac-swap off 1", "testpmd>")
+        self.vm0_testpmd.execute_cmd("set promisc 1 on")
+        self.vm0_testpmd.execute_cmd("set promisc 0 on")
+
+        time.sleep(2)
+        mac = self.vm0_testpmd.get_port_mac(0)
+        sndIP = "10.0.0.1"
+        sndIPv6 = "::1"
+        pkts = {
+            "IP/UDP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IP(src="%s", chksum=0xf)/UDP(chksum=0xf)/("X"*46)'
+            % (mac, sndIP),
+            "IP/TCP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IP(src="%s", chksum=0xf)/TCP(chksum=0xf)/("X"*46)'
+            % (mac, sndIP),
+            "IP/SCTP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IP(src="%s", chksum=0xf)/SCTP(chksum=0x0)/("X"*48)'
+            % (mac, sndIP),
+            "IPv6/UDP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)'
+            % (mac, sndIPv6),
+            "IPv6/TCP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)'
+            % (mac, sndIPv6),
+        }
+
+        expIP = sndIP
+        expIPv6 = sndIPv6
+        pkts_ref = {
+            "IP/UDP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IP(src="%s")/UDP()/("X"*46)'
+            % (mac, expIP),
+            "IP/TCP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IP(src="%s")/TCP()/("X"*46)'
+            % (mac, expIP),
+            "IP/SCTP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IP(src="%s")/SCTP()/("X"*48)'
+            % (mac, expIP),
+            "IPv6/UDP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IPv6(src="%s")/UDP()/("X"*46)'
+            % (mac, expIPv6),
+            "IPv6/TCP": 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=100)/IPv6(src="%s")/TCP()/("X"*46)'
+            % (mac, expIPv6),
+        }
+
+        self.checksum_enablehw(0, self.vm_dut_0)
+        self.checksum_enablehw(1, self.vm_dut_0)
+
+        self.vm0_testpmd.execute_cmd("start")
+        result = self.checksum_validate(pkts, pkts_ref)
+
+        # Validate checksum on the receive packet
+        out = self.vm0_testpmd.execute_cmd("stop")
+        bad_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out)
+        bad_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out)
+        self.verify(bad_ipcsum == 3, "Bad-ipcsum check error")
+        self.verify(bad_l4csum == 5, "Bad-l4csum check error")
+
+        self.verify(len(result) == 0, ",".join(list(result.values())))
+
     @check_supported_nic(
         ["ICE_100G-E810C_QSFP", "ICE_25G-E810C_SFP", "ICE_25G-E810_XXV_SFP"]
     )
@@ -429,8 +493,8 @@ class TestVfOffload(TestCase):
         expIPv6 = sndIPv6
 
         pkts_outer = {
-            "IP/UDP/VXLAN-GPE": f'IP(src = "{sndIP}") / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN()',
-            "IP/UDP/VXLAN-GPE/ETH": f'IP(src = "{sndIP}") / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN() / Ether()',
+            "IP/UDP/VXLAN-GPE": f'IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN()',
+            "IP/UDP/VXLAN-GPE/ETH": f'IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN() / Ether()',
             "IPv6/UDP/VXLAN-GPE": f'IPv6(src = "{sndIPv6}") / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN()',
             "IPv6/UDP/VXLAN-GPE/ETH": f'IPv6(src = "{sndIPv6}") / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN() / Ether()',
             "IP/GRE": f'IP(src = "{sndIP}", proto = 47, chksum = 0xff) / GRE()',
@@ -452,13 +516,12 @@ class TestVfOffload(TestCase):
         }
 
         if self.dcf_mode == "enable":
-            pkts_outer[
-                "IP/UDP/VXLAN/ETH"
-            ] = f'IP(src = "{sndIP}") / UDP(sport = 4789, dport = 4789, chksum = 0xff) / VXLAN() / Ether()'
-            pkts_outer[
-                "IPv6/UDP/VXLAN/ETH"
-            ] = f'IPv6(src = "{sndIPv6}") / UDP(sport = 4789, dport = 4789, chksum = 0xff) / VXLAN() / Ether()'
-
+            pkts_outer.update(
+                {
+                    "IP/UDP/VXLAN/ETH": f'IP(src = "{sndIP}") / UDP(sport = 4789, dport = 4789, chksum = 0xff) / VXLAN() / Ether()',
+                    "IPv6/UDP/VXLAN/ETH": f'IPv6(src = "{sndIPv6}") / UDP(sport = 4789, dport = 4789, chksum = 0xff) / VXLAN() / Ether()',
+                }
+            )
         pkts = {
             key_outer
             + "/"
@@ -494,13 +557,156 @@ class TestVfOffload(TestCase):
         }
 
         if self.dcf_mode == "enable":
-            pkts_outer_ref[
-                "IP/UDP/VXLAN/ETH"
-            ] = f'IP(src = "{sndIP}") / UDP(sport = 4789, dport = 4789) / VXLAN() / Ether()'
-            pkts_outer_ref[
-                "IPv6/UDP/VXLAN/ETH"
-            ] = f'IPv6(src = "{sndIPv6}") / UDP(sport = 4789, dport = 4789) / VXLAN() / Ether()'
+            pkts_outer.update(
+                {
+                    "IP/UDP/VXLAN/ETH": f'IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 4789, dport = 4789) / VXLAN() / Ether()',
+                    "IPv6/UDP/VXLAN/ETH": f'IPv6(src = "{sndIPv6}") / UDP(sport = 4789, dport = 4789) / VXLAN() / Ether()',
+                }
+            )
+        pkts_ref = {
+            key_outer
+            + "/"
+            + key_inner: f'Ether(dst="{mac}", src="52:00:00:00:00:00") / '
+            + p_outer
+            + " / "
+            + p_inner
+            for key_outer, p_outer in pkts_outer_ref.items()
+            for key_inner, p_inner in pkts_inner_ref.items()
+        }
+
+        self.checksum_enablehw_tunnel(0, self.vm_dut_0)
+        self.checksum_enablehw_tunnel(1, self.vm_dut_0)
+
+        self.vm0_testpmd.execute_cmd("start")
+        self.vm0_testpmd.wait_link_status_up(0)
+        self.vm0_testpmd.wait_link_status_up(1)
+        result = self.checksum_validate(pkts, pkts_ref)
+        # Validate checksum on the receive packet
+        out = self.vm0_testpmd.execute_cmd("stop")
+        bad_outer_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-outer-ipcsum:", out)
+        bad_outer_l4csum = self.vm0_testpmd.get_pmd_value("Bad-outer-l4csum:", out)
+        bad_inner_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out)
+        bad_inner_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out)
+        if self.dcf_mode == "enable":
+            # Outer IP checksum error = 7 (outer-ip) * 6 (inner packet)
+            self.verify(bad_outer_ipcsum == 42, "Bad-outer-ipcsum check error")
+            # Outer IP checksum error = 8 (outer-UDP) * 6 (inner packet)
+            self.verify(bad_outer_l4csum == 48, "Bad-outer-l4csum check error")
+            # Outer L4 checksum error = 14 (outer packets) * 3 (inner-IP)
+            self.verify(bad_inner_ipcsum == 42, "Bad-ipcsum check error")
+            # Outer L4 checksum error = 14 (outer packets) * 6 (inner-L4)
+            self.verify(bad_inner_l4csum == 84, "Bad-l4csum check error")
+        else:
+            # Outer IP checksum error = 6 (outer-ip) * 6 (inner packet)
+            self.verify(bad_outer_ipcsum == 36, "Bad-outer-ipcsum check error")
+            # Outer IP checksum error = 6 (outer-UDP) * 6 (inner packet)
+            self.verify(bad_outer_l4csum == 36, "Bad-outer-l4csum check error")
+            # Outer L4 checksum error = 12 (outer packets) * 3 (inner-IP)
+            self.verify(bad_inner_ipcsum == 36, "Bad-ipcsum check error")
+            # Outer L4 checksum error = 12 (outer packets) * 6 (inner-L4)
+            self.verify(bad_inner_l4csum == 72, "Bad-l4csum check error")
+
+        self.verify(len(result) == 0, ",".join(list(result.values())))
+
+    @check_supported_nic(
+        ["ICE_100G-E810C_QSFP", "ICE_25G-E810C_SFP", "ICE_25G-E810_XXV_SFP"]
+    )
+    @skip_unsupported_pkg(["os default"])
+    def test_checksum_offload_vlan_tunnel_enable(self):
+        """
+        Enable HW checksum offload.
+        Send packet with inner and outer incorrect checksum,
+        can rx it and report the checksum error,
+        verify forwarded packets have correct checksum.
+        """
+        self.launch_testpmd(
+            dcf_flag=self.dcf_mode,
+            param="--portmask=%s " % (self.portMask) + "--enable-rx-cksum " + "",
+        )
+        self.vm0_testpmd.execute_cmd("set fwd csum")
+        self.vm0_testpmd.execute_cmd("set promisc 1 on")
+        self.vm0_testpmd.execute_cmd("set promisc 0 on")
+        self.vm0_testpmd.execute_cmd("csum mac-swap off 0", "testpmd>")
+        self.vm0_testpmd.execute_cmd("csum mac-swap off 1", "testpmd>")
+        time.sleep(2)
+        port_id_0 = 0
+        mac = self.vm0_testpmd.get_port_mac(0)
+        sndIP = "10.0.0.1"
+        sndIPv6 = "::1"
+        expIP = sndIP
+        expIPv6 = sndIPv6
+
+        pkts_outer = {
+            "VLAN/IP/UDP/VXLAN-GPE": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN()',
+            "VLAN/IP/UDP/VXLAN-GPE/ETH": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN() / Ether()',
+            "VLAN/IPv6/UDP/VXLAN-GPE": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}") / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN()',
+            "VLAN/IPv6/UDP/VXLAN-GPE/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}") / UDP(sport = 4790, dport = 4790, chksum = 0xff) / VXLAN() / Ether()',
+            "VLAN/IP/GRE": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", proto = 47, chksum = 0xff) / GRE()',
+            "VLAN/IP/GRE/ETH": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", proto = 47, chksum = 0xff) / GRE() / Ether()',
+            "VLAN/IP/NVGRE/ETH": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", proto = 47, chksum = 0xff) / GRE(key_present=1, proto=0x6558, key=0x00000100) / Ether()',
+            "VLAN/IPv6/GRE": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}", nh = 47) / GRE()',
+            "VLAN/IPv6/GRE/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}", nh = 47) / GRE() / Ether()',
+            "VLAN/IPv6/NVGRE/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}", nh = 47) / GRE(key_present=1, proto=0x6558, key=0x00000100) / Ether()',
+            "VLAN/IP/UDP/GTPU": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", chksum = 0xff) / UDP(dport = 2152, chksum = 0xff) / GTP_U_Header(gtp_type=255, teid=0x123456)',
+            "VLAN/IPv6/UDP/GTPU": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}") / UDP(dport = 2152, chksum = 0xff) / GTP_U_Header(gtp_type=255, teid=0x123456)',
+        }
+        pkts_inner = {
+            "IP/UDP": f'IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 29999, dport = 30000, chksum = 0xff) / Raw("x" * 100)',
+            "IP/TCP": f'IP(src = "{sndIP}", chksum = 0xff) / TCP(sport = 29999, dport = 30000, chksum = 0xff) / Raw("x" * 100)',
+            "IP/SCTP": f'IP(src = "{sndIP}", chksum = 0xff) / SCTP(sport = 29999, dport = 30000, chksum = 0x0) / Raw("x" * 128)',
+            "IPv6/UDP": f'IPv6(src = "{sndIPv6}") / UDP(sport = 29999, dport = 30000, chksum = 0xff) / Raw("x" * 100)',
+            "IPv6/TCP": f'IPv6(src = "{sndIPv6}") / TCP(sport = 29999, dport = 30000, chksum = 0xff) / Raw("x" * 100)',
+            "IPv6/SCTP": f'IPv6(src = "{sndIPv6}") / SCTP(sport = 29999, dport = 30000, chksum = 0x0) / Raw("x" * 128)',
+        }
+
+        if self.dcf_mode == "enable":
+            pkts_outer.update(
+                {
+                    "VLAN/IP/UDP/VXLAN/ETH": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 4789, dport = 4789, chksum = 0xff) / VXLAN() / Ether()',
+                    "VLAN/IPv6/UDP/VXLAN/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}") / UDP(sport = 4789, dport = 4789, chksum = 0xff) / VXLAN() / Ether()',
+                }
+            )
+        pkts = {
+            key_outer
+            + "/"
+            + key_inner: f'Ether(dst="{mac}", src="52:00:00:00:00:00") / '
+            + p_outer
+            + " / "
+            + p_inner
+            for key_outer, p_outer in pkts_outer.items()
+            for key_inner, p_inner in pkts_inner.items()
+        }
 
+        pkts_outer_ref = {
+            "VLAN/IP/UDP/VXLAN-GPE": f'Dot1Q(vlan=100) / IP(src = "{expIP}") / UDP(sport = 4790, dport = 4790) / VXLAN()',
+            "VLAN/IP/UDP/VXLAN-GPE/ETH": f'Dot1Q(vlan=100) / IP(src = "{expIP}") / UDP(sport = 4790, dport = 4790) / VXLAN() / Ether()',
+            "VLAN/IPv6/UDP/VXLAN-GPE": f'Dot1Q(vlan=100) / IPv6(src = "{expIPv6}") / UDP(sport = 4790, dport = 4790) / VXLAN()',
+            "VLAN/IPv6/UDP/VXLAN-GPE/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{expIPv6}") / UDP(sport = 4790, dport = 4790) / VXLAN() / Ether()',
+            "VLAN/IP/GRE": f'Dot1Q(vlan=100) / IP(src = "{expIP}", proto = 47) / GRE()',
+            "VLAN/IP/GRE/ETH": f'Dot1Q(vlan=100) / IP(src = "{expIP}", proto = 47) / GRE() / Ether()',
+            "VLAN/IP/NVGRE/ETH": f'Dot1Q(vlan=100) / IP(src = "{expIP}", proto = 47) / GRE(key_present=1, proto=0x6558, key=0x00000100) / Ether()',
+            "VLAN/IPv6/GRE": f'Dot1Q(vlan=100) / IPv6(src = "{expIPv6}", nh = 47) / GRE()',
+            "VLAN/IPv6/GRE/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{expIPv6}", nh = 47) / GRE() / Ether()',
+            "VLAN/IPv6/NVGRE/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{expIPv6}", nh = 47) / GRE(key_present=1, proto=0x6558, key=0x00000100) / Ether()',
+            "VLAN/IP/UDP/GTPU": f'Dot1Q(vlan=100) / IP(src = "{expIP}") / UDP(dport = 2152) / GTP_U_Header(gtp_type=255, teid=0x123456)',
+            "VLAN/IPv6/UDP/GTPU": f'Dot1Q(vlan=100) / IPv6(src = "{expIPv6}") / UDP(dport = 2152) / GTP_U_Header(gtp_type=255, teid=0x123456)',
+        }
+        pkts_inner_ref = {
+            "IP/UDP": f'IP(src = "{expIP}") / UDP(sport = 29999, dport = 30000) / Raw("x" * 100)',
+            "IP/TCP": f'IP(src = "{expIP}") / TCP(sport = 29999, dport = 30000) / Raw("x" * 100)',
+            "IP/SCTP": f'IP(src = "{expIP}") / SCTP(sport = 29999, dport = 30000) / Raw("x" * 128)',
+            "IPv6/UDP": f'IPv6(src = "{expIPv6}") / UDP(sport = 29999, dport = 30000) / Raw("x" * 100)',
+            "IPv6/TCP": f'IPv6(src = "{expIPv6}") / TCP(sport = 29999, dport = 30000) / Raw("x" * 100)',
+            "IPv6/SCTP": f'IPv6(src = "{expIPv6}") / SCTP(sport = 29999, dport = 30000) / Raw("x" * 128)',
+        }
+
+        if self.dcf_mode == "enable":
+            pkts_outer.update(
+                {
+                    "VLAN/IP/UDP/VXLAN/ETH": f'Dot1Q(vlan=100) / IP(src = "{sndIP}", chksum = 0xff) / UDP(sport = 4789, dport = 4789) / VXLAN() / Ether()',
+                    "VLAN/IPv6/UDP/VXLAN/ETH": f'Dot1Q(vlan=100) / IPv6(src = "{sndIPv6}") / UDP(sport = 4789, dport = 4789) / VXLAN() / Ether()',
+                }
+            )
         pkts_ref = {
             key_outer
             + "/"
@@ -526,14 +732,22 @@ class TestVfOffload(TestCase):
         bad_inner_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out)
         bad_inner_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out)
         if self.dcf_mode == "enable":
-            self.verify(bad_outer_ipcsum == 24, "Bad-outer-ipcsum check error")
+            # Outer IP checksum error = 7 (outer-ip) * 6 (inner packet)
+            self.verify(bad_outer_ipcsum == 42, "Bad-outer-ipcsum check error")
+            # Outer IP checksum error = 8 (outer-UDP) * 6 (inner packet)
             self.verify(bad_outer_l4csum == 48, "Bad-outer-l4csum check error")
+            # Outer L4 checksum error = 14 (outer packets) * 3 (inner-IP)
             self.verify(bad_inner_ipcsum == 42, "Bad-ipcsum check error")
+            # Outer L4 checksum error = 14 (outer packets) * 6 (inner-L4)
             self.verify(bad_inner_l4csum == 84, "Bad-l4csum check error")
         else:
-            self.verify(bad_outer_ipcsum == 24, "Bad-outer-ipcsum check error")
+            # Outer IP checksum error = 6 (outer-ip) * 6 (inner packet)
+            self.verify(bad_outer_ipcsum == 36, "Bad-outer-ipcsum check error")
+            # Outer IP checksum error = 6 (outer-UDP) * 6 (inner packet)
             self.verify(bad_outer_l4csum == 36, "Bad-outer-l4csum check error")
+            # Outer L4 checksum error = 12 (outer packets) * 3 (inner-IP)
             self.verify(bad_inner_ipcsum == 36, "Bad-ipcsum check error")
+            # Outer L4 checksum error = 12 (outer packets) * 6 (inner-L4)
             self.verify(bad_inner_l4csum == 72, "Bad-l4csum check error")
 
         self.verify(len(result) == 0, ",".join(list(result.values())))
