+ ikeys.append(
+ gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
+ )
+ if integ_alg:
+ integ = f"integ-alg {integ_alg.alg_name} " \
+ f"integ-key {ikeys[i].hex()} "
+ else:
+ integ = u""
+ tmp_f1.write(
+ f"exec set interface ip address loop0 "
+ f"{tun_ips[u'ip1'] + i * addr_incr}/32\n"
+ f"exec create ipip tunnel "
+ f"src {tun_ips[u'ip1'] + i * addr_incr} "
+ f"dst {tun_ips[u'ip2']} "
+ f"p2p\n"
+ f"exec ipsec sa add {i} "
+ f"spi {spi_d[u'spi_1'] + i} "
+ f"crypto-alg {crypto_alg.alg_name} "
+ f"crypto-key {ckeys[i].hex()} "
+ f"{integ}"
+ f"esp\n"
+ f"exec ipsec sa add {100000 + i} "
+ f"spi {spi_d[u'spi_2'] + i} "
+ f"crypto-alg {crypto_alg.alg_name} "
+ f"crypto-key {ckeys[i].hex()} "
+ f"{integ}"
+ f"esp\n"
+ f"exec ipsec tunnel protect ipip{i} "
+ f"sa-out {i} "
+ f"sa-in {100000 + i} "
+ f"add\n"
+ )
+ vat.execute_script(
+ tmp_fn1, nodes[u"DUT1"], timeout=1800, json_out=False,
+ copy_on_execute=True,
+ history=bool(n_tunnels < 100)
+ )
+ os.remove(tmp_fn1)
+
+ with open(tmp_fn1, 'w') as tmp_f1:
+ for i in range(existing_tunnels, n_tunnels):
+ tmp_f1.write(
+ f"exec set interface unnumbered ipip{i} use {if1_n}\n"
+ f"exec set interface state ipip{i} up\n"
+ f"exec ip route add "
+ f"{raddr_ip2 + i}/{len(raddr_ip2.packed)*8} "
+ f"via ipip{i}\n"
+ )
+ vat.execute_script(
+ tmp_fn1, nodes[u"DUT1"], timeout=1800, json_out=False,
+ copy_on_execute=True,
+ history=bool(n_tunnels < 100)
+ )
+ os.remove(tmp_fn1)
+
+ return ckeys, ikeys
+
+ @staticmethod
+ def _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=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
+ IPv4/IPv6 address (ip2).
+ :param if2_key: VPP node 2 / TG node (in case of 2-node topology)
+ interface key from topology file.
+ :param n_tunnels: Number of tunnel interfaces to be there at the end.
+ :param crypto_alg: The encryption algorithm name.
+ :param ckeys: List of encryption keys.
+ :param integ_alg: The integrity algorithm name.
+ :param ikeys: List of integrity keys.
+ :param spi_d: Dictionary with SPIs for VPP node 1 and VPP node 2.
+ :param addr_incr: IP / IPv6 address incremental step.
+ :param existing_tunnels: Number of tunnel interfaces before creation.
+ Useful mainly for reconf tests. Default 0.
+ :type nodes: dict
+ :type tun_ips: dict
+ :type if2_key: str
+ :type n_tunnels: int
+ :type crypto_alg: CryptoAlg
+ :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
+ """
+ tmp_fn2 = u"/tmp/ipsec_create_tunnel_dut2.config"
+ if2_n = Topology.get_interface_name(nodes[u"DUT2"], if2_key)
+
+ vat = VatExecutor()
+ with open(tmp_fn2, 'w') as tmp_f2:
+ if not existing_tunnels:
+ tmp_f2.write(
+ f"exec set interface ip address {if2_n}"
+ f" {tun_ips[u'ip2']}/{len(tun_ips[u'ip2'].packed)*8*3/4}\n"
+ )
+ for i in range(existing_tunnels, n_tunnels):
+ if integ_alg:
+ integ = f"integ-alg {integ_alg.alg_name} " \
+ f"integ-key {ikeys[i].hex()} "
+ else:
+ integ = u""
+ tmp_f2.write(
+ f"exec create ipip tunnel "
+ f"src {tun_ips[u'ip2']} "
+ f"dst {tun_ips[u'ip1'] + i * addr_incr} "
+ f"p2p\n"
+ f"exec ipsec sa add {100000 + i} "
+ f"spi {spi_d[u'spi_2'] + i} "
+ f"crypto-alg {crypto_alg.alg_name} "
+ f"crypto-key {ckeys[i].hex()} "
+ f"{integ}"
+ f"esp\n"
+ f"exec ipsec sa add {i} "
+ f"spi {spi_d[u'spi_1'] + i} "
+ f"crypto-alg {crypto_alg.alg_name} "
+ f"crypto-key {ckeys[i].hex()} "
+ f"{integ}"
+ f"esp\n"
+ f"exec ipsec tunnel protect ipip{i} "
+ f"sa-out {100000 + i} "
+ f"sa-in {i} "
+ f"add\n"
+ )
+ vat.execute_script(
+ tmp_fn2, nodes[u"DUT2"], timeout=1800, json_out=False,
+ copy_on_execute=True,
+ history=bool(n_tunnels < 100)
+ )
+ os.remove(tmp_fn2)
+
+ with open(tmp_fn2, 'w') as tmp_f2:
+ if not existing_tunnels:
+ tmp_f2.write(
+ f"exec ip route add {tun_ips[u'ip1']}/8 "
+ f"via {tun_ips[u'ip2'] - 1} {if2_n}\n"
+ )
+ for i in range(existing_tunnels, n_tunnels):
+ tmp_f2.write(
+ f"exec set interface unnumbered ipip{i} use {if2_n}\n"
+ f"exec set interface state ipip{i} up\n"
+ f"exec ip route add "
+ f"{raddr_ip1 + i}/{len(raddr_ip1.packed)*8} "
+ f"via ipip{i}\n"
+ )
+ vat.execute_script(
+ tmp_fn2, nodes[u"DUT2"], timeout=1800, json_out=False,
+ copy_on_execute=True,
+ history=bool(n_tunnels < 100)
+ )
+ os.remove(tmp_fn2)
+
+ @staticmethod
+ def _ipsec_create_loopback_dut1_papi(nodes, tun_ips, if1_key, if2_key):
+ """Create loopback interface and set IP address on VPP node 1 interface
+ using PAPI.
+
+ :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
+ IPv4/IPv6 address (ip2).
+ :param if1_key: VPP node 1 interface key from topology file.
+ :param if2_key: VPP node 2 / TG node (in case of 2-node topology)
+ interface key from topology file.
+ :type nodes: dict
+ :type tun_ips: dict
+ :type if1_key: str
+ :type if2_key: str
+ """
+ with PapiSocketExecutor(nodes[u"DUT1"]) as papi_exec:
+ # Create loopback interface on DUT1, set it to up state
+ cmd = u"create_loopback_instance"
+ args = dict(
+ 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']}"
+ loop_sw_if_idx = papi_exec.add(cmd, **args). \
+ get_sw_if_index(err_msg)
+ cmd = u"sw_interface_set_flags"
+ args = dict(
+ sw_if_index=loop_sw_if_idx,
+ flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
+ )
+ err_msg = f"Failed to set loopback interface state up " \
+ f"on host {nodes[u'DUT1'][u'host']}"
+ papi_exec.add(cmd, **args).get_reply(err_msg)
+ # Set IP address on VPP node 1 interface
+ cmd = u"sw_interface_add_del_address"
+ args = dict(
+ sw_if_index=InterfaceUtil.get_interface_index(
+ nodes[u"DUT1"], if1_key
+ ),
+ is_add=True,
+ del_all=False,
+ prefix=IPUtil.create_prefix_object(
+ tun_ips[u"ip2"] - 1, 96 if tun_ips[u"ip2"].version == 6
+ else 24
+ )
+ )
+ err_msg = f"Failed to set IP address on interface {if1_key} " \
+ f"on host {nodes[u'DUT1'][u'host']}"
+ papi_exec.add(cmd, **args).get_reply(err_msg)
+ cmd2 = u"ip_neighbor_add_del"
+ args2 = dict(
+ is_add=1,
+ neighbor=dict(
+ sw_if_index=Topology.get_interface_sw_index(