hs-test: more debug output in http3 test
[vpp.git] / test / test_ipsec_tun_if_esp.py
index d10ad21..a7f91b9 100644 (file)
@@ -5,11 +5,10 @@ import copy
 from scapy.layers.ipsec import SecurityAssociation, ESP
 from scapy.layers.l2 import Ether, GRE, Dot1Q
 from scapy.packet import Raw, bind_layers
-from scapy.layers.inet import IP, UDP
-from scapy.layers.inet6 import IPv6
+from scapy.layers.inet import IP, UDP, ICMP
+from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
 from scapy.contrib.mpls import MPLS
-from framework import tag_fixme_vpp_workers
-from framework import VppTestRunner
+from asfframework import VppTestRunner, tag_fixme_vpp_workers
 from template_ipsec import (
     TemplateIpsec,
     IpsecTun4Tests,
@@ -70,7 +69,7 @@ def config_tun_params(p, encryption_type, tun_if, src=None, dst=None):
 
     p.scapy_tun_sa = SecurityAssociation(
         encryption_type,
-        spi=p.vpp_tun_spi,
+        spi=p.scapy_tun_spi,
         crypt_algo=p.crypt_algo,
         crypt_key=crypt_key,
         auth_algo=p.auth_algo,
@@ -81,7 +80,7 @@ def config_tun_params(p, encryption_type, tun_if, src=None, dst=None):
     )
     p.vpp_tun_sa = SecurityAssociation(
         encryption_type,
-        spi=p.scapy_tun_spi,
+        spi=p.vpp_tun_spi,
         crypt_algo=p.crypt_algo,
         crypt_key=crypt_key,
         auth_algo=p.auth_algo,
@@ -114,7 +113,7 @@ def config_tra_params(p, encryption_type, tun_if):
 
     p.scapy_tun_sa = SecurityAssociation(
         encryption_type,
-        spi=p.vpp_tun_spi,
+        spi=p.scapy_tun_spi,
         crypt_algo=p.crypt_algo,
         crypt_key=crypt_key,
         auth_algo=p.auth_algo,
@@ -124,7 +123,7 @@ def config_tra_params(p, encryption_type, tun_if):
     )
     p.vpp_tun_sa = SecurityAssociation(
         encryption_type,
-        spi=p.scapy_tun_spi,
+        spi=p.vpp_tun_spi,
         crypt_algo=p.crypt_algo,
         crypt_key=crypt_key,
         auth_algo=p.auth_algo,
@@ -147,8 +146,8 @@ class TemplateIpsec4TunProtect(object):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -160,8 +159,8 @@ class TemplateIpsec4TunProtect(object):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -176,8 +175,8 @@ class TemplateIpsec4TunProtect(object):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -191,8 +190,8 @@ class TemplateIpsec4TunProtect(object):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -300,7 +299,7 @@ class TemplateIpsec4TunIfEspUdp(TemplateIpsec4TunProtect, TemplateIpsec):
                 # which strips them
                 self.assertTrue(rx.haslayer(UDP))
                 self.assert_equal(rx[UDP].sport, p.nat_header.sport)
-                self.assert_equal(rx[UDP].dport, 4500)
+                self.assert_equal(rx[UDP].dport, p.nat_header.dport)
 
                 pkt = sa.decrypt(rx[IP])
                 if not pkt.haslayer(IP):
@@ -322,8 +321,8 @@ class TemplateIpsec4TunIfEspUdp(TemplateIpsec4TunProtect, TemplateIpsec):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -337,14 +336,15 @@ class TemplateIpsec4TunIfEspUdp(TemplateIpsec4TunProtect, TemplateIpsec):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
             p.crypt_key,
             self.vpp_esp_protocol,
-            flags=p.flags,
+            flags=p.flags
+            | VppEnum.vl_api_ipsec_sad_flags_t.IPSEC_API_SAD_FLAG_IS_INBOUND,
             udp_src=p.nat_header.sport,
             udp_dst=p.nat_header.dport,
         )
@@ -367,6 +367,29 @@ class TemplateIpsec4TunIfEspUdp(TemplateIpsec4TunProtect, TemplateIpsec):
         super(TemplateIpsec4TunIfEspUdp, self).tearDown()
 
 
+class TemplateIpsec4TunTfc:
+    """IPsec IPv4 tunnel with TFC"""
+
+    def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1, payload_size=54):
+        pkt = (
+            IP(src=src, dst=dst, len=28 + payload_size)
+            / ICMP()
+            / Raw(b"X" * payload_size)
+            / Padding(b"Y" * 100)
+        )
+        return [
+            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) / sa.encrypt(pkt)
+            for i in range(count)
+        ]
+
+    def verify_decrypted(self, p, rxs):
+        for rx in rxs:
+            self.assert_equal(rx[IP].src, p.remote_tun_if_host)
+            self.assert_equal(rx[IP].dst, self.pg1.remote_ip4)
+            self.assert_equal(rx[IP].len, len(rx[IP]))
+            self.assert_packet_checksums_valid(rx)
+
+
 class TestIpsec4TunIfEsp1(TemplateIpsec4TunIfEsp, IpsecTun4Tests):
     """Ipsec ESP - TUN tests"""
 
@@ -429,6 +452,24 @@ class TestIpsec4TunIfEspUdpGCM(TemplateIpsec4TunIfEspUdp, IpsecTun4Tests):
         p.salt = 0
 
 
+class TestIpsec4TunIfEspUdpUpdate(TemplateIpsec4TunIfEspUdp, IpsecTun4Tests):
+    """Ipsec ESP UDP update tests"""
+
+    tun4_input_node = "ipsec4-tun-input"
+
+    def setUp(self):
+        super(TestIpsec4TunIfEspUdpUpdate, self).setUp()
+        p = self.ipv4_params
+        p.nat_header = UDP(sport=6565, dport=7676)
+        config_tun_params(p, self.encryption_type, p.tun_if)
+        p.tun_sa_in.update_vpp_config(
+            udp_src=p.nat_header.dport, udp_dst=p.nat_header.sport
+        )
+        p.tun_sa_out.update_vpp_config(
+            udp_src=p.nat_header.sport, udp_dst=p.nat_header.dport
+        )
+
+
 class TestIpsec4TunIfEsp2(TemplateIpsec4TunIfEsp, IpsecTcpTests):
     """Ipsec ESP - TCP tests"""
 
@@ -443,8 +484,8 @@ class TemplateIpsec6TunProtect(object):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -455,8 +496,8 @@ class TemplateIpsec6TunProtect(object):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -470,8 +511,8 @@ class TemplateIpsec6TunProtect(object):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -484,8 +525,8 @@ class TemplateIpsec6TunProtect(object):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -561,6 +602,155 @@ class TemplateIpsec6TunIfEsp(TemplateIpsec6TunProtect, TemplateIpsec):
         super(TemplateIpsec6TunIfEsp, self).tearDown()
 
 
+class TemplateIpsec6TunIfEspUdp(TemplateIpsec6TunProtect, TemplateIpsec):
+    """IPsec6 UDP tunnel interface tests"""
+
+    tun4_encrypt_node_name = "esp6-encrypt-tun"
+    tun4_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"]
+    encryption_type = ESP
+
+    @classmethod
+    def setUpClass(cls):
+        super(TemplateIpsec6TunIfEspUdp, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TemplateIpsec6TunIfEspUdp, cls).tearDownClass()
+
+    def verify_encrypted(self, p, sa, rxs):
+        for rx in rxs:
+            try:
+                # ensure the UDP ports are correct before we decrypt
+                # which strips them
+                self.assertTrue(rx.haslayer(UDP))
+                self.assert_equal(rx[UDP].sport, p.nat_header.sport)
+                self.assert_equal(rx[UDP].dport, p.nat_header.dport)
+
+                pkt = sa.decrypt(rx[IP])
+                if not pkt.haslayer(IP):
+                    pkt = IP(pkt[Raw].load)
+
+                self.assert_packet_checksums_valid(pkt)
+                self.assert_equal(
+                    pkt[IP].dst, "1111:1111:1111:1111:1111:1111:1111:1111"
+                )
+                self.assert_equal(pkt[IP].src, self.pg1.remote_ip6)
+            except (IndexError, AssertionError):
+                self.logger.debug(ppp("Unexpected packet:", rx))
+                try:
+                    self.logger.debug(ppp("Decrypted packet:", pkt))
+                except:
+                    pass
+                raise
+
+    def config_sa_tra(self, p):
+        config_tun_params(p, self.encryption_type, p.tun_if)
+
+        p.tun_sa_out = VppIpsecSA(
+            self,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
+            p.auth_algo_vpp_id,
+            p.auth_key,
+            p.crypt_algo_vpp_id,
+            p.crypt_key,
+            self.vpp_esp_protocol,
+            flags=p.flags,
+            udp_src=p.nat_header.sport,
+            udp_dst=p.nat_header.dport,
+        )
+        p.tun_sa_out.add_vpp_config()
+
+        p.tun_sa_in = VppIpsecSA(
+            self,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
+            p.auth_algo_vpp_id,
+            p.auth_key,
+            p.crypt_algo_vpp_id,
+            p.crypt_key,
+            self.vpp_esp_protocol,
+            flags=p.flags
+            | VppEnum.vl_api_ipsec_sad_flags_t.IPSEC_API_SAD_FLAG_IS_INBOUND,
+            udp_src=p.nat_header.sport,
+            udp_dst=p.nat_header.dport,
+        )
+        p.tun_sa_in.add_vpp_config()
+
+    def setUp(self):
+        super(TemplateIpsec6TunIfEspUdp, self).setUp()
+
+        p = self.ipv6_params
+        p.flags = VppEnum.vl_api_ipsec_sad_flags_t.IPSEC_API_SAD_FLAG_UDP_ENCAP
+        p.nat_header = UDP(sport=5454, dport=4500)
+
+        self.tun_if = self.pg0
+
+        self.config_network(p)
+        self.config_sa_tra(p)
+        self.config_protect(p)
+
+    def tearDown(self):
+        super(TemplateIpsec6TunIfEspUdp, self).tearDown()
+
+
+class TemplateIpsec6TunTfc:
+    """IPsec IPv6 tunnel with TFC"""
+
+    def gen_encrypt_pkts6(self, p, sa, sw_intf, src, dst, count=1, payload_size=54):
+        return [
+            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
+            / sa.encrypt(
+                IPv6(src=src, dst=dst, hlim=p.inner_hop_limit, fl=p.inner_flow_label)
+                / ICMPv6EchoRequest(id=0, seq=1, data="X" * payload_size)
+                / Padding(b"Y" * 100)
+            )
+            for i in range(count)
+        ]
+
+    def verify_decrypted6(self, p, rxs):
+        for rx in rxs:
+            self.assert_equal(rx[IPv6].src, p.remote_tun_if_host)
+            self.assert_equal(rx[IPv6].dst, self.pg1.remote_ip6)
+            self.assert_equal(rx[IPv6].plen, len(rx[IPv6].payload))
+            self.assert_packet_checksums_valid(rx)
+
+
+class TestIpsec6TunIfEspUdp(TemplateIpsec6TunIfEspUdp, IpsecTun6Tests):
+    """Ipsec ESP 6 UDP tests"""
+
+    tun6_input_node = "ipsec6-tun-input"
+    tun6_encrypt_node_name = "esp6-encrypt-tun"
+    tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"]
+
+    def setUp(self):
+        super(TestIpsec6TunIfEspUdp, self).setUp()
+
+    def test_keepalive(self):
+        """IPSEC6 NAT Keepalive"""
+        self.verify_keepalive(self.ipv6_params)
+
+
+class TestIpsec6TunIfEspUdpGCM(TemplateIpsec6TunIfEspUdp, IpsecTun6Tests):
+    """Ipsec ESP 6 UDP GCM tests"""
+
+    tun6_input_node = "ipsec6-tun-input"
+    tun6_encrypt_node_name = "esp6-encrypt-tun"
+    tun6_decrypt_node_name = ["esp6-decrypt-tun", "esp6-decrypt-tun-post"]
+
+    def setUp(self):
+        super(TestIpsec6TunIfEspUdpGCM, self).setUp()
+        p = self.ipv6_params
+        p.auth_algo_vpp_id = VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_NONE
+        p.crypt_algo_vpp_id = (
+            VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_GCM_256
+        )
+        p.crypt_algo = "AES-GCM"
+        p.auth_algo = "NULL"
+        p.crypt_key = b"JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h"
+        p.salt = 0
+
+
 class TestIpsec6TunIfEsp1(TemplateIpsec6TunIfEsp, IpsecTun6Tests):
     """Ipsec ESP - TUN tests"""
 
@@ -860,8 +1050,8 @@ class TestIpsec4TunIfEspAll(TemplateIpsec4TunProtect, TemplateIpsec, IpsecTun4):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -872,8 +1062,8 @@ class TestIpsec4TunIfEspAll(TemplateIpsec4TunProtect, TemplateIpsec, IpsecTun4):
         )
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1041,13 +1231,35 @@ class TestIpsec4TunIfEspNoAlgo(TemplateIpsec4TunProtect, TemplateIpsec, IpsecTun
         self.config_sa_tra(p)
         self.config_protect(p)
 
-        tx = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4, dst=p.remote_tun_if_host)
+        tx = self.gen_pkts(
+            self.pg1, src=self.pg1.remote_ip4, dst=p.remote_tun_if_host, count=127
+        )
+        self.send_and_assert_no_replies(self.pg1, tx)
+
+        self.unconfig_protect(p)
+        self.unconfig_sa(p)
+        self.unconfig_network(p)
+
+    def test_tun_44_async(self):
+        """IPSec SA with NULL algos using async crypto"""
+        p = self.ipv4_params
+
+        self.vapi.ipsec_set_async_mode(async_enable=True)
+        self.config_network(p)
+        self.config_sa_tra(p)
+        self.config_protect(p)
+
+        tx = self.gen_pkts(
+            self.pg1, src=self.pg1.remote_ip4, dst=p.remote_tun_if_host, count=127
+        )
         self.send_and_assert_no_replies(self.pg1, tx)
 
         self.unconfig_protect(p)
         self.unconfig_sa(p)
         self.unconfig_network(p)
 
+        self.vapi.ipsec_set_async_mode(async_enable=False)
+
 
 @tag_fixme_vpp_workers
 class TestIpsec6MultiTunIfEsp(TemplateIpsec6TunProtect, TemplateIpsec, IpsecTun6):
@@ -1166,8 +1378,8 @@ class TestIpsecGreTebIfEsp(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1180,8 +1392,8 @@ class TestIpsecGreTebIfEsp(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1301,8 +1513,8 @@ class TestIpsecGreTebVlanIfEsp(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1315,8 +1527,8 @@ class TestIpsecGreTebVlanIfEsp(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1425,8 +1637,8 @@ class TestIpsecGreTebIfEspTra(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1437,8 +1649,8 @@ class TestIpsecGreTebIfEspTra(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1549,8 +1761,8 @@ class TestIpsecGreTebUdpIfEspTra(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1564,8 +1776,8 @@ class TestIpsecGreTebUdpIfEspTra(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1673,8 +1885,8 @@ class TestIpsecGreIfEsp(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1687,8 +1899,8 @@ class TestIpsecGreIfEsp(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1792,8 +2004,8 @@ class TestIpsecGreIfEspTra(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1804,8 +2016,8 @@ class TestIpsecGreIfEspTra(TemplateIpsec, IpsecTun4Tests):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1844,6 +2056,8 @@ class TestIpsecGreIfEspTra(TemplateIpsec, IpsecTun4Tests):
         self.send_and_assert_no_replies(self.tun_if, tx)
         node_name = "/err/%s/unsup_payload" % self.tun4_decrypt_node_name[0]
         self.assertEqual(1, self.statistics.get_err_counter(node_name))
+        err = p.tun_sa_in.get_err("unsup_payload")
+        self.assertEqual(err, 1)
 
 
 class TestIpsecGre6IfEspTra(TemplateIpsec, IpsecTun6Tests):
@@ -1910,8 +2124,8 @@ class TestIpsecGre6IfEspTra(TemplateIpsec, IpsecTun6Tests):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -1922,8 +2136,8 @@ class TestIpsecGre6IfEspTra(TemplateIpsec, IpsecTun6Tests):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -2049,8 +2263,8 @@ class TestIpsecMGreIfEspTra4(TemplateIpsec, IpsecTun4):
             p.vpp_tra_spi = p.vpp_tra_spi + ii
             p.tun_sa_out = VppIpsecSA(
                 self,
-                p.scapy_tun_sa_id,
-                p.scapy_tun_spi,
+                p.vpp_tun_sa_id,
+                p.vpp_tun_spi,
                 p.auth_algo_vpp_id,
                 p.auth_key,
                 p.crypt_algo_vpp_id,
@@ -2061,8 +2275,8 @@ class TestIpsecMGreIfEspTra4(TemplateIpsec, IpsecTun4):
 
             p.tun_sa_in = VppIpsecSA(
                 self,
-                p.vpp_tun_sa_id,
-                p.vpp_tun_spi,
+                p.scapy_tun_sa_id,
+                p.scapy_tun_spi,
                 p.auth_algo_vpp_id,
                 p.auth_key,
                 p.crypt_algo_vpp_id,
@@ -2206,8 +2420,8 @@ class TestIpsecMGreIfEspTra6(TemplateIpsec, IpsecTun6):
             p.vpp_tra_spi = p.vpp_tra_spi + ii
             p.tun_sa_out = VppIpsecSA(
                 self,
-                p.scapy_tun_sa_id,
-                p.scapy_tun_spi,
+                p.vpp_tun_sa_id,
+                p.vpp_tun_spi,
                 p.auth_algo_vpp_id,
                 p.auth_key,
                 p.crypt_algo_vpp_id,
@@ -2218,8 +2432,8 @@ class TestIpsecMGreIfEspTra6(TemplateIpsec, IpsecTun6):
 
             p.tun_sa_in = VppIpsecSA(
                 self,
-                p.vpp_tun_sa_id,
-                p.vpp_tun_spi,
+                p.scapy_tun_sa_id,
+                p.scapy_tun_spi,
                 p.auth_algo_vpp_id,
                 p.auth_key,
                 p.crypt_algo_vpp_id,
@@ -2322,9 +2536,14 @@ class TestIpsec4TunProtect(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4):
         self.unconfig_network(p)
 
 
+@tag_fixme_vpp_workers
+class TestIpsec4TunProtectTfc(TemplateIpsec4TunTfc, TestIpsec4TunProtect):
+    """IPsec IPv4 Tunnel protect with TFC - transport mode"""
+
+
 @tag_fixme_vpp_workers
 class TestIpsec4TunProtectUdp(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4):
-    """IPsec IPv4 Tunnel protect - transport mode"""
+    """IPsec IPv4 UDP Tunnel protect - transport mode"""
 
     def setUp(self):
         super(TestIpsec4TunProtectUdp, self).setUp()
@@ -2366,6 +2585,11 @@ class TestIpsec4TunProtectUdp(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4
         self.verify_keepalive(self.ipv4_params)
 
 
+@tag_fixme_vpp_workers
+class TestIpsec4TunProtectUdpTfc(TemplateIpsec4TunTfc, TestIpsec4TunProtectUdp):
+    """IPsec IPv4 UDP Tunnel protect with TFC - transport mode"""
+
+
 @tag_fixme_vpp_workers
 class TestIpsec4TunProtectTun(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4):
     """IPsec IPv4 Tunnel protect - tunnel mode"""
@@ -2640,6 +2864,11 @@ class TestIpsec6TunProtect(TemplateIpsec, TemplateIpsec6TunProtect, IpsecTun6):
         self.unconfig_network(p)
 
 
+@tag_fixme_vpp_workers
+class TestIpsec6TunProtectTfc(TemplateIpsec6TunTfc, TestIpsec6TunProtect):
+    """IPsec IPv6 Tunnel protect with TFC - transport mode"""
+
+
 @tag_fixme_vpp_workers
 class TestIpsec6TunProtectTun(TemplateIpsec, TemplateIpsec6TunProtect, IpsecTun6):
     """IPsec IPv6 Tunnel protect - tunnel mode"""
@@ -2807,8 +3036,8 @@ class TemplateIpsecItf4(object):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -2822,8 +3051,8 @@ class TemplateIpsecItf4(object):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -2831,7 +3060,8 @@ class TemplateIpsecItf4(object):
             self.vpp_esp_protocol,
             dst,
             src,
-            flags=p.flags,
+            flags=p.flags
+            | VppEnum.vl_api_ipsec_sad_flags_t.IPSEC_API_SAD_FLAG_IS_INBOUND,
         )
         p.tun_sa_in.add_vpp_config()
 
@@ -2937,6 +3167,20 @@ class TestIpsecItf4(TemplateIpsec, TemplateIpsecItf4, IpsecTun4):
 
         self.tun4_encrypt_node_name = "esp4-encrypt-tun"
 
+        # update the SA tunnel
+        config_tun_params(
+            p, self.encryption_type, None, self.pg2.local_ip4, self.pg2.remote_ip4
+        )
+        p.tun_sa_in.update_vpp_config(
+            is_tun=True, tun_src=self.pg2.remote_ip4, tun_dst=self.pg2.local_ip4
+        )
+        p.tun_sa_out.update_vpp_config(
+            is_tun=True, tun_src=self.pg2.local_ip4, tun_dst=self.pg2.remote_ip4
+        )
+        self.verify_tun_44(p, count=n_pkts)
+        self.assertEqual(p.tun_if.get_rx_stats(), 5 * n_pkts)
+        self.assertEqual(p.tun_if.get_tx_stats(), 4 * n_pkts)
+
         self.vapi.cli("clear interfaces")
 
         # rekey - create new SAs and update the tunnel protection
@@ -3041,6 +3285,11 @@ class TestIpsecItf4(TemplateIpsec, TemplateIpsecItf4, IpsecTun4):
         self.unconfig_network(p)
 
 
+@tag_fixme_vpp_workers
+class TestIpsecItf4Tfc(TemplateIpsec4TunTfc, TestIpsecItf4):
+    """IPsec Interface IPv4 with TFC"""
+
+
 class TestIpsecItf4MPLS(TemplateIpsec, TemplateIpsecItf4, IpsecTun4):
     """IPsec Interface MPLSoIPv4"""
 
@@ -3137,8 +3386,8 @@ class TemplateIpsecItf6(object):
 
         p.tun_sa_out = VppIpsecSA(
             self,
-            p.scapy_tun_sa_id,
-            p.scapy_tun_spi,
+            p.vpp_tun_sa_id,
+            p.vpp_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -3154,8 +3403,8 @@ class TemplateIpsecItf6(object):
 
         p.tun_sa_in = VppIpsecSA(
             self,
-            p.vpp_tun_sa_id,
-            p.vpp_tun_spi,
+            p.scapy_tun_sa_id,
+            p.scapy_tun_spi,
             p.auth_algo_vpp_id,
             p.auth_key,
             p.crypt_algo_vpp_id,
@@ -3353,6 +3602,11 @@ class TestIpsecItf6(TemplateIpsec, TemplateIpsecItf6, IpsecTun6):
         self.unconfig_network(p)
 
 
+@tag_fixme_vpp_workers
+class TestIpsecItf6Tfc(TemplateIpsec6TunTfc, TestIpsecItf6):
+    """IPsec Interface IPv6 with TFC"""
+
+
 class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4):
     """Ipsec P2MP ESP v4 tests"""
 
@@ -3449,8 +3703,8 @@ class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4):
             p.hop_limit = ii + 10
             p.tun_sa_out = VppIpsecSA(
                 self,
-                p.scapy_tun_sa_id,
-                p.scapy_tun_spi,
+                p.vpp_tun_sa_id,
+                p.vpp_tun_spi,
                 p.auth_algo_vpp_id,
                 p.auth_key,
                 p.crypt_algo_vpp_id,
@@ -3465,8 +3719,8 @@ class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4):
 
             p.tun_sa_in = VppIpsecSA(
                 self,
-                p.vpp_tun_sa_id,
-                p.vpp_tun_spi,
+                p.scapy_tun_sa_id,
+                p.scapy_tun_spi,
                 p.auth_algo_vpp_id,
                 p.auth_key,
                 p.crypt_algo_vpp_id,