IPsec: add 4, 40 and 400 tunnel policy tests
[csit.git] / resources / libraries / python / IPsecUtil.py
index 3c3997a..f75daf9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2020 Cisco and/or its affiliates.
+# Copyright (c) 2021 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
@@ -243,12 +243,14 @@ class IPsecUtil:
     def get_integ_alg_key_len(integ_alg):
         """Return integrity algorithm key length.
 
+        None argument is accepted, returning zero.
+
         :param integ_alg: Integrity algorithm.
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :returns: Key length.
         :rtype: int
         """
-        return integ_alg.key_len
+        return 0 if integ_alg is None else integ_alg.key_len
 
     @staticmethod
     def get_integ_alg_scapy_name(integ_alg):
@@ -320,6 +322,30 @@ class IPsecUtil:
         with PapiSocketExecutor(node) as papi_exec:
             papi_exec.add(cmd, **args).get_reply(err_msg)
 
+    @staticmethod
+    def vpp_ipsec_crypto_sw_scheduler_set_worker(
+            node, worker_index, crypto_enable=False):
+        """Enable or disable crypto on specific vpp worker threads.
+
+        :param node: VPP node to enable or disable crypto for worker threads.
+        :param worker_index: VPP worker thread index.
+        :param crypto_enable: Disable or enable crypto work.
+        :type node: dict
+        :type worker_index: int
+        :type crypto_enable: bool
+        :raises RuntimeError: If failed to enable or disable crypto for worker
+            thread or if no API reply received.
+        """
+        cmd = u"crypto_sw_scheduler_set_worker"
+        err_msg = f"Failed to disable/enable crypto for worker thread " \
+            f"on host {node[u'host']}"
+        args = dict(
+            worker_index=worker_index,
+            crypto_enable=crypto_enable
+        )
+        with PapiSocketExecutor(node) as papi_exec:
+            papi_exec.add(cmd, **args).get_reply(err_msg)
+
     @staticmethod
     def vpp_ipsec_add_sad_entry(
             node, sad_id, spi, crypto_alg, crypto_key, integ_alg=None,
@@ -342,7 +368,7 @@ class IPsecUtil:
         :type spi: int
         :type crypto_alg: CryptoAlg
         :type crypto_key: str
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type integ_key: str
         :type tunnel_src: str
         :type tunnel_dst: str
@@ -372,7 +398,7 @@ class IPsecUtil:
             src_addr = u""
             dst_addr = u""
 
-        cmd = u"ipsec_sad_entry_add_del"
+        cmd = u"ipsec_sad_entry_add_del_v2"
         err_msg = f"Failed to add Security Association Database entry " \
             f"on host {node[u'host']}"
         sad_entry = dict(
@@ -385,6 +411,10 @@ class IPsecUtil:
             flags=flags,
             tunnel_src=str(src_addr),
             tunnel_dst=str(dst_addr),
+            tunnel_flags=int(
+                TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+            ),
+            dscp=int(IpDscp.IP_API_DSCP_CS0),
             protocol=int(IPsecProto.IPSEC_API_PROTO_ESP),
             udp_src_port=4500,  # default value in api
             udp_dst_port=4500  # default value in api
@@ -422,7 +452,7 @@ class IPsecUtil:
         :type spi: int
         :type crypto_alg: CryptoAlg
         :type crypto_key: str
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type integ_key: str
         :type tunnel_src: str
         :type tunnel_dst: str
@@ -449,8 +479,8 @@ class IPsecUtil:
                     integ = f"integ-alg {integ_alg.alg_name} " \
                         f"integ-key {integ_key.hex()}" \
                         if integ_alg else u""
-                    tunnel = f"tunnel-src {src_addr + i * addr_incr} " \
-                        f"tunnel-dst {dst_addr + i * addr_incr}" \
+                    tunnel = f"tunnel src {src_addr + i * addr_incr} " \
+                        f"tunnel dst {dst_addr + i * addr_incr}" \
                         if tunnel_src and tunnel_dst else u""
                     conf = f"exec ipsec sa add {sad_id + i} esp spi {spi + i} "\
                         f"crypto-alg {crypto_alg.alg_name} " \
@@ -482,7 +512,7 @@ class IPsecUtil:
                     IPsecSadFlags.IPSEC_API_SAD_FLAG_IS_TUNNEL_V6
                 )
 
-        cmd = u"ipsec_sad_entry_add_del"
+        cmd = u"ipsec_sad_entry_add_del_v2"
         err_msg = f"Failed to add Security Association Database entry " \
             f"on host {node[u'host']}"
 
@@ -496,6 +526,10 @@ class IPsecUtil:
             flags=flags,
             tunnel_src=str(src_addr),
             tunnel_dst=str(dst_addr),
+            tunnel_flags=int(
+                TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+            ),
+            dscp=int(IpDscp.IP_API_DSCP_CS0),
             protocol=int(IPsecProto.IPSEC_API_PROTO_ESP),
             udp_src_port=4500,  # default value in api
             udp_dst_port=4500  # default value in api
@@ -519,7 +553,7 @@ class IPsecUtil:
     @staticmethod
     def vpp_ipsec_set_ip_route(
             node, n_tunnels, tunnel_src, traffic_addr, tunnel_dst, interface,
-            raddr_range):
+            raddr_range, dst_mac=None):
         """Set IP address and route on interface.
 
         :param node: VPP node to add config on.
@@ -531,6 +565,7 @@ class IPsecUtil:
         :param raddr_range: Mask specifying range of Policy selector Remote IP
             addresses. Valid values are from 1 to 32 in case of IPv4 and to 128
             in case of IPv6.
+        :param dst_mac: The MAC address of destination tunnels.
         :type node: dict
         :type n_tunnels: int
         :type tunnel_src: str
@@ -538,6 +573,7 @@ class IPsecUtil:
         :type tunnel_dst: str
         :type interface: str
         :type raddr_range: int
+        :type dst_mac: str
         """
         tunnel_src = ip_address(tunnel_src)
         tunnel_dst = ip_address(tunnel_dst)
@@ -556,7 +592,11 @@ class IPsecUtil:
                         f"exec ip route add {traffic_addr + i}/" \
                         f"{128 if traffic_addr.version == 6 else 32} " \
                         f"via {tunnel_dst + i * addr_incr} {if_name}\n"
+                    if dst_mac:
+                        conf = f"{conf}exec set ip neighbor {if_name} " \
+                               f"{tunnel_dst + i * addr_incr} {dst_mac}\n"
                     tmp_file.write(conf)
+
             VatExecutor().execute_script(
                 tmp_filename, node, timeout=300, json_out=False,
                 copy_on_execute=True
@@ -577,8 +617,21 @@ class IPsecUtil:
             is_multipath=0,
             route=None
         )
-        err_msg = f"Failed to configure IP addresses and IP routes " \
-            f"on interface {interface} on host {node[u'host']}"
+        cmd3 = u"ip_neighbor_add_del"
+        args3 = dict(
+            is_add=True,
+            neighbor=dict(
+                sw_if_index=Topology.get_interface_sw_index(node, interface),
+                flags=0,
+                mac_address=str(dst_mac),
+                ip_address=None
+            )
+        )
+        err_msg = f"Failed to configure IP addresses, IP routes and " \
+            f"IP neighbor on interface {interface} on host {node[u'host']}" \
+            if dst_mac \
+            else f"Failed to configure IP addresses and IP routes " \
+                 f"on interface {interface} on host {node[u'host']}"
 
         with PapiSocketExecutor(node) as papi_exec:
             for i in range(n_tunnels):
@@ -593,6 +646,11 @@ class IPsecUtil:
                 history = bool(not 1 < i < n_tunnels - 2)
                 papi_exec.add(cmd1, history=history, **args1).\
                     add(cmd2, history=history, **args2)
+                if dst_mac:
+                    args3[u"neighbor"][u"ip_address"] = ip_address(
+                        tunnel_dst + i * addr_incr
+                    )
+                    papi_exec.add(cmd3, history=history, **args3)
             papi_exec.get_replies(err_msg)
 
     @staticmethod
@@ -817,6 +875,8 @@ class IPsecUtil:
             raddr_ip2, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT1 node using VAT.
 
+        Generate random keys and return them (so DUT2 or TG can decrypt).
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -839,11 +899,13 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type raddr_ip2: IPv4Address or IPv6Address
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
+        :returns: Generated ckeys and ikeys.
+        :rtype: List[bytes], List[bytes]
         """
         tmp_fn1 = u"/tmp/ipsec_create_tunnel_dut1.config"
         if1_n = Topology.get_interface_name(nodes[u"DUT1"], if1_key)
@@ -870,10 +932,10 @@ class IPsecUtil:
                 ckeys.append(
                     gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
                 )
+                ikeys.append(
+                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
+                )
                 if integ_alg:
-                    ikeys.append(
-                        gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
-                    )
                     integ = f"integ-alg {integ_alg.alg_name} " \
                         f"integ-key {ikeys[i].hex()} "
                 else:
@@ -933,6 +995,9 @@ class IPsecUtil:
             ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT2 node using VAT.
 
+        This method accesses keys generated by DUT1 method
+        and does not return anything.
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -953,9 +1018,9 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type ckeys: list
-        :type integ_alg: IntegAlg
-        :type ikeys: list
+        :type ckeys: Sequence[bytes]
+        :type integ_alg: Optional[IntegAlg]
+        :type ikeys: Sequence[bytes]
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
@@ -1045,9 +1110,11 @@ class IPsecUtil:
         """
         with PapiSocketExecutor(nodes[u"DUT1"]) as papi_exec:
             # Create loopback interface on DUT1, set it to up state
-            cmd = u"create_loopback"
+            cmd = u"create_loopback_instance"
             args = dict(
-                mac_address=0
+                mac_address=0,
+                is_specified=False,
+                user_instance=0,
             )
             err_msg = f"Failed to create loopback interface " \
                 f"on host {nodes[u'DUT1'][u'host']}"
@@ -1106,6 +1173,8 @@ class IPsecUtil:
             raddr_ip2, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT1 node using PAPI.
 
+        Generate random keys and return them (so DUT2 or TG can decrypt).
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -1128,11 +1197,13 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type raddr_ip2: IPv4Address or IPv6Address
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
+        :returns: Generated ckeys and ikeys.
+        :rtype: List[bytes], List[bytes]
         """
         if not existing_tunnels:
             loop_sw_if_idx = IPsecUtil._ipsec_create_loopback_dut1_papi(
@@ -1235,10 +1306,9 @@ class IPsecUtil:
                 ckeys.append(
                     gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
                 )
-                if integ_alg:
-                    ikeys.append(
-                        gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
-                    )
+                ikeys.append(
+                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
+                )
                 # SAD entry for outband / tx path
                 args[u"entry"][u"sad_id"] = i
                 args[u"entry"][u"spi"] = spi_d[u"spi_1"] + i
@@ -1354,6 +1424,9 @@ class IPsecUtil:
             ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT2 node using PAPI.
 
+        This method accesses keys generated by DUT1 method
+        and does not return anything.
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -1374,9 +1447,9 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type ckeys: list
-        :type integ_alg: IntegAlg
-        :type ikeys: list
+        :type ckeys: Sequence[bytes]
+        :type integ_alg: Optional[IntegAlg]
+        :type ikeys: Sequence[bytes]
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
@@ -1475,10 +1548,9 @@ class IPsecUtil:
                 ckeys.append(
                     gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
                 )
-                if integ_alg:
-                    ikeys.append(
-                        gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
-                    )
+                ikeys.append(
+                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
+                )
                 # SAD entry for outband / tx path
                 args[u"entry"][u"sad_id"] = 100000 + i
                 args[u"entry"][u"spi"] = spi_d[u"spi_2"] + i
@@ -1605,9 +1677,13 @@ class IPsecUtil:
     def vpp_ipsec_create_tunnel_interfaces(
             nodes, tun_if1_ip_addr, tun_if2_ip_addr, if1_key, if2_key,
             n_tunnels, crypto_alg, integ_alg, raddr_ip1, raddr_ip2, raddr_range,
-            existing_tunnels=0):
+            existing_tunnels=0, return_keys=False):
         """Create multiple IPsec tunnel interfaces between two VPP nodes.
 
+        Some deployments (e.g. devicetest) need to know the generated keys.
+        But other deployments (e.g. scale perf test) would get spammed
+        if we returned keys every time.
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_if1_ip_addr: VPP node 1 ipsec tunnel interface IPv4/IPv6
             address.
@@ -1628,6 +1704,7 @@ class IPsecUtil:
             and to 128 in case of IPv6.
         :param existing_tunnels: Number of tunnel interfaces before creation.
             Useful mainly for reconf tests. Default 0.
+        :param return_keys: Whether generated keys should be returned.
         :type nodes: dict
         :type tun_if1_ip_addr: str
         :type tun_if2_ip_addr: str
@@ -1635,11 +1712,14 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optonal[IntegAlg]
         :type raddr_ip1: string
         :type raddr_ip2: string
         :type raddr_range: int
         :type existing_tunnels: int
+        :type return_keys: bool
+        :returns: Ckeys, ikeys, spi_1, spi_2.
+        :rtype: Optional[List[bytes], List[bytes], int, int]
         """
         n_tunnels = int(n_tunnels)
         existing_tunnels = int(existing_tunnels)
@@ -1661,25 +1741,27 @@ class IPsecUtil:
                 nodes, tun_ips, if1_key, if2_key, n_tunnels, crypto_alg,
                 integ_alg, raddr_ip2, addr_incr, spi_d, existing_tunnels
             )
-            if u"DUT2" not in nodes.keys():
-                return ckeys[0], ikeys[0], spi_d[u"spi_1"], spi_d[u"spi_2"]
-            IPsecUtil._ipsec_create_tunnel_interfaces_dut2_vat(
-                nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
-                integ_alg, ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels
-            )
+            if u"DUT2" in nodes.keys():
+                IPsecUtil._ipsec_create_tunnel_interfaces_dut2_vat(
+                    nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
+                    integ_alg, ikeys, raddr_ip1, addr_incr, spi_d,
+                    existing_tunnels
+                )
         else:
             ckeys, ikeys = IPsecUtil._ipsec_create_tunnel_interfaces_dut1_papi(
                 nodes, tun_ips, if1_key, if2_key, n_tunnels, crypto_alg,
                 integ_alg, raddr_ip2, addr_incr, spi_d, existing_tunnels
             )
-            if u"DUT2" not in nodes.keys():
-                return ckeys[0], ikeys[0], spi_d[u"spi_1"], spi_d[u"spi_2"]
-            IPsecUtil._ipsec_create_tunnel_interfaces_dut2_papi(
-                nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
-                integ_alg, ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels
-            )
+            if u"DUT2" in nodes.keys():
+                IPsecUtil._ipsec_create_tunnel_interfaces_dut2_papi(
+                    nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
+                    integ_alg, ikeys, raddr_ip1, addr_incr, spi_d,
+                    existing_tunnels
+                )
 
-        return None, None, None, None
+        if return_keys:
+            return ckeys, ikeys, spi_d[u"spi_1"], spi_d[u"spi_2"]
+        return None
 
     @staticmethod
     def _create_ipsec_script_files(dut, instances):
@@ -1744,7 +1826,7 @@ class IPsecUtil:
         :type if2_ip_addr: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type raddr_ip1: string
         :type raddr_ip2: string
         :type raddr_range: int
@@ -1777,10 +1859,10 @@ class IPsecUtil:
                 gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg)), u"hex"
             )
             integ = u""
+            ikey = getattr(
+                gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg)), u"hex"
+            )
             if integ_alg:
-                ikey = getattr(
-                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg)), u"hex"
-                )
                 integ = (
                     f"integ-alg {integ_alg.alg_name} "
                     f"local-integ-key {ikey} "
@@ -1858,7 +1940,7 @@ class IPsecUtil:
         :type interface2: str or int
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type tunnel_ip1: str
         :type tunnel_ip2: str
         :type raddr_ip1: string
@@ -1880,12 +1962,12 @@ class IPsecUtil:
             IPsecUtil.get_integ_alg_key_len(integ_alg)
         ).decode() if integ_alg else u""
 
+        rmac = Topology.get_interface_mac(nodes[u"DUT2"], interface2) \
+            if u"DUT2" in nodes.keys() \
+            else Topology.get_interface_mac(nodes[u"TG"], interface2)
         IPsecUtil.vpp_ipsec_set_ip_route(
             nodes[u"DUT1"], n_tunnels, tunnel_ip1, raddr_ip2, tunnel_ip2,
-            interface1, raddr_range)
-        IPsecUtil.vpp_ipsec_set_ip_route(
-            nodes[u"DUT2"], n_tunnels, tunnel_ip2, raddr_ip1, tunnel_ip1,
-            interface2, raddr_range)
+            interface1, raddr_range, rmac)
 
         IPsecUtil.vpp_ipsec_add_spd(nodes[u"DUT1"], spd_id)
         IPsecUtil.vpp_ipsec_spd_add_if(nodes[u"DUT1"], spd_id, interface1)
@@ -1898,17 +1980,6 @@ class IPsecUtil:
             proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
         )
 
-        IPsecUtil.vpp_ipsec_add_spd(nodes[u"DUT2"], spd_id)
-        IPsecUtil.vpp_ipsec_spd_add_if(nodes[u"DUT2"], spd_id, interface2)
-        IPsecUtil.vpp_ipsec_policy_add(
-            nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
-            proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
-        )
-        IPsecUtil.vpp_ipsec_policy_add(
-            nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
-            proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
-        )
-
         IPsecUtil.vpp_ipsec_add_sad_entries(
             nodes[u"DUT1"], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
             integ_alg, integ_key, tunnel_ip1, tunnel_ip2
@@ -1918,30 +1989,49 @@ class IPsecUtil:
         )
 
         IPsecUtil.vpp_ipsec_add_sad_entries(
-            nodes[u"DUT2"], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
-            integ_alg, integ_key, tunnel_ip1, tunnel_ip2
+            nodes[u"DUT1"], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
+            integ_alg, integ_key, tunnel_ip2, tunnel_ip1
         )
         IPsecUtil.vpp_ipsec_spd_add_entries(
-            nodes[u"DUT2"], n_tunnels, spd_id, p_lo, True, sa_id_1, raddr_ip2
+            nodes[u"DUT1"], n_tunnels, spd_id, p_lo, True, sa_id_2, raddr_ip1
         )
 
-        IPsecUtil.vpp_ipsec_add_sad_entries(
-            nodes[u"DUT2"], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
-            integ_alg, integ_key, tunnel_ip2, tunnel_ip1
-        )
+        if u"DUT2" in nodes.keys():
+            IPsecUtil.vpp_ipsec_set_ip_route(
+                nodes[u"DUT2"], n_tunnels, tunnel_ip2, raddr_ip1, tunnel_ip1,
+                interface2, raddr_range)
+
+            IPsecUtil.vpp_ipsec_add_spd(nodes[u"DUT2"], spd_id)
+            IPsecUtil.vpp_ipsec_spd_add_if(nodes[u"DUT2"], spd_id, interface2)
+            IPsecUtil.vpp_ipsec_policy_add(
+                nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS,
+                inbound=False, proto=50, laddr_range=u"100.0.0.0/8",
+                raddr_range=u"100.0.0.0/8"
+            )
+            IPsecUtil.vpp_ipsec_policy_add(
+                nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS,
+                inbound=True, proto=50, laddr_range=u"100.0.0.0/8",
+                raddr_range=u"100.0.0.0/8"
+            )
 
-        IPsecUtil.vpp_ipsec_spd_add_entries(
-            nodes[u"DUT2"], n_tunnels, spd_id, p_lo, False, sa_id_2, raddr_ip1
-        )
+            IPsecUtil.vpp_ipsec_add_sad_entries(
+                nodes[u"DUT2"], n_tunnels, sa_id_1, spi_1, crypto_alg,
+                crypto_key, integ_alg, integ_key, tunnel_ip1, tunnel_ip2
+            )
+            IPsecUtil.vpp_ipsec_spd_add_entries(
+                nodes[u"DUT2"], n_tunnels, spd_id, p_lo, True, sa_id_1,
+                raddr_ip2
+            )
 
-        IPsecUtil.vpp_ipsec_add_sad_entries(
-            nodes[u"DUT1"], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
-            integ_alg, integ_key, tunnel_ip2, tunnel_ip1
-        )
+            IPsecUtil.vpp_ipsec_add_sad_entries(
+                nodes[u"DUT2"], n_tunnels, sa_id_2, spi_2, crypto_alg,
+                crypto_key, integ_alg, integ_key, tunnel_ip2, tunnel_ip1
+            )
+            IPsecUtil.vpp_ipsec_spd_add_entries(
+                nodes[u"DUT2"], n_tunnels, spd_id, p_lo, False, sa_id_2,
+                raddr_ip1
+            )
 
-        IPsecUtil.vpp_ipsec_spd_add_entries(
-            nodes[u"DUT1"], n_tunnels, spd_id, p_lo, True, sa_id_2, raddr_ip1
-        )
 
     @staticmethod
     def vpp_ipsec_show(node):