X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FIPsecUtil.py;h=2e6574f40e31f6a1da7d28a6ce126865db53eb2e;hb=14a71b74b414df7616ccb5ada3d50ecb90d96bae;hp=8f464d5a05e9fb2327966dacf33d780c520488b5;hpb=526d34a0373b73185ecc6a877724418135efa88e;p=csit.git diff --git a/resources/libraries/python/IPsecUtil.py b/resources/libraries/python/IPsecUtil.py index 8f464d5a05..2e6574f40e 100644 --- a/resources/libraries/python/IPsecUtil.py +++ b/resources/libraries/python/IPsecUtil.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 Cisco and/or its affiliates. +# Copyright (c) 2020 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: @@ -22,10 +22,12 @@ from string import ascii_letters from ipaddress import ip_network, ip_address -from resources.libraries.python.IPUtil import IPUtil from resources.libraries.python.InterfaceUtil import InterfaceUtil, \ InterfaceStatusFlags +from resources.libraries.python.IPAddress import IPAddress +from resources.libraries.python.IPUtil import IPUtil from resources.libraries.python.PapiExecutor import PapiSocketExecutor +from resources.libraries.python.ssh import scp_node from resources.libraries.python.topology import Topology from resources.libraries.python.VatExecutor import VatExecutor @@ -82,8 +84,8 @@ class IntegAlg(Enum): class IPsecProto(IntEnum): """IPsec protocol.""" - ESP = 1 - SEC_AH = 0 + IPSEC_API_PROTO_ESP = 50 + IPSEC_API_PROTO_AH = 51 class IPsecSadFlags(IntEnum): @@ -228,7 +230,7 @@ class IPsecUtil: :returns: IPsecProto enum ESP object. :rtype: IPsecProto """ - return int(IPsecProto.ESP) + return int(IPsecProto.IPSEC_API_PROTO_ESP) @staticmethod def ipsec_proto_ah(): @@ -237,7 +239,7 @@ class IPsecUtil: :returns: IPsecProto enum AH object. :rtype: IPsecProto """ - return int(IPsecProto.SEC_AH) + return int(IPsecProto.IPSEC_API_PROTO_AH) @staticmethod def vpp_ipsec_select_backend(node, protocol, index=1): @@ -326,10 +328,10 @@ class IPsecUtil: flags=flags, tunnel_src=str(src_addr), tunnel_dst=str(dst_addr), - protocol=int(IPsecProto.ESP) + protocol=int(IPsecProto.IPSEC_API_PROTO_ESP) ) args = dict( - is_add=1, + is_add=True, entry=sad_entry ) with PapiSocketExecutor(node) as papi_exec: @@ -435,10 +437,10 @@ class IPsecUtil: flags=flags, tunnel_src=str(src_addr), tunnel_dst=str(dst_addr), - protocol=int(IPsecProto.ESP) + protocol=int(IPsecProto.IPSEC_API_PROTO_ESP) ) args = dict( - is_add=1, + is_add=True, entry=sad_entry ) with PapiSocketExecutor(node) as papi_exec: @@ -546,7 +548,7 @@ class IPsecUtil: err_msg = f"Failed to add Security Policy Database " \ f"on host {node[u'host']}" args = dict( - is_add=1, + is_add=True, spd_id=int(spd_id) ) with PapiSocketExecutor(node) as papi_exec: @@ -567,7 +569,7 @@ class IPsecUtil: err_msg = f"Failed to add interface {interface} to Security Policy " \ f"Database {spd_id} on host {node[u'host']}" args = dict( - is_add=1, + is_add=True, sw_if_index=InterfaceUtil.get_interface_index(node, interface), spd_id=int(spd_id) ) @@ -627,20 +629,20 @@ class IPsecUtil: spd_entry = dict( spd_id=int(spd_id), priority=int(priority), - is_outbound=0 if inbound else 1, + is_outbound=not inbound, sa_id=int(sa_id) if sa_id else 0, policy=action.policy_int_repr, protocol=int(proto) if proto else 0, - remote_address_start=IPUtil.create_ip_address_object( + remote_address_start=IPAddress.create_ip_address_object( ip_network(raddr_range, strict=False).network_address ), - remote_address_stop=IPUtil.create_ip_address_object( + remote_address_stop=IPAddress.create_ip_address_object( ip_network(raddr_range, strict=False).broadcast_address ), - local_address_start=IPUtil.create_ip_address_object( + local_address_start=IPAddress.create_ip_address_object( ip_network(laddr_range, strict=False).network_address ), - local_address_stop=IPUtil.create_ip_address_object( + local_address_stop=IPAddress.create_ip_address_object( ip_network(laddr_range, strict=False).broadcast_address ), remote_port_start=int(rport_range.split(u"-")[0]) if rport_range @@ -653,7 +655,7 @@ class IPsecUtil: else 65535 ) args = dict( - is_add=1, + is_add=True, entry=spd_entry ) with PapiSocketExecutor(node) as papi_exec: @@ -717,16 +719,16 @@ class IPsecUtil: spd_entry = dict( spd_id=int(spd_id), priority=int(priority), - is_outbound=0 if inbound else 1, + is_outbound=not inbound, sa_id=int(sa_id) if sa_id else 0, policy=IPsecUtil.policy_action_protect().policy_int_repr, protocol=0, - remote_address_start=IPUtil.create_ip_address_object(raddr_ip), - remote_address_stop=IPUtil.create_ip_address_object(raddr_ip), - local_address_start=IPUtil.create_ip_address_object( + remote_address_start=IPAddress.create_ip_address_object(raddr_ip), + remote_address_stop=IPAddress.create_ip_address_object(raddr_ip), + local_address_start=IPAddress.create_ip_address_object( ip_network(laddr_range, strict=False).network_address ), - local_address_stop=IPUtil.create_ip_address_object( + local_address_stop=IPAddress.create_ip_address_object( ip_network(laddr_range, strict=False).broadcast_address ), remote_port_start=0, @@ -735,16 +737,16 @@ class IPsecUtil: local_port_stop=65535 ) args = dict( - is_add=1, + is_add=True, entry=spd_entry ) with PapiSocketExecutor(node) as papi_exec: for i in range(n_entries): args[u"entry"][u"remote_address_start"][u"un"] = \ - IPUtil.union_addr(raddr_ip + i) + IPAddress.union_addr(raddr_ip + i) args[u"entry"][u"remote_address_stop"][u"un"] = \ - IPUtil.union_addr(raddr_ip + i) + IPAddress.union_addr(raddr_ip + i) history = bool(not 1 < i < n_entries - 2) papi_exec.add(cmd, history=history, **args) papi_exec.get_replies(err_msg) @@ -752,7 +754,8 @@ class IPsecUtil: @staticmethod def vpp_ipsec_create_tunnel_interfaces( nodes, if1_ip_addr, if2_ip_addr, if1_key, if2_key, n_tunnels, - crypto_alg, integ_alg, raddr_ip1, raddr_ip2, raddr_range): + crypto_alg, integ_alg, raddr_ip1, raddr_ip2, raddr_range, + existing_tunnels=0): """Create multiple IPsec tunnel interfaces between two VPP nodes. :param nodes: VPP nodes to create tunnel interfaces. @@ -760,7 +763,7 @@ class IPsecUtil: :param if2_ip_addr: VPP node 2 interface IPv4/IPv6 address. :param if1_key: VPP node 1 interface key from topology file. :param if2_key: VPP node 2 interface key from topology file. - :param n_tunnels: Number of tunnel interfaces to create. + :param n_tunnels: Number of tunnel interfaces to be there at the end. :param crypto_alg: The encryption algorithm name. :param integ_alg: The integrity algorithm name. :param raddr_ip1: Policy selector remote IPv4/IPv6 start address for the @@ -770,6 +773,8 @@ class IPsecUtil: :param raddr_range: Mask specifying range of Policy selector Remote IPv4/IPv6 addresses. Valid values are from 1 to 32 in case of IPv4 and to 128 in case of IPv6. + :param existing_tunnels: Number of tunnel interfaces before creation. + Useful mainly for reconf tests. Default 0. :type nodes: dict :type if1_ip_addr: str :type if2_ip_addr: str @@ -781,8 +786,10 @@ class IPsecUtil: :type raddr_ip1: string :type raddr_ip2: string :type raddr_range: int + :type existing_tunnels: int """ n_tunnels = int(n_tunnels) + existing_tunnels = int(existing_tunnels) spi_1 = 100000 spi_2 = 200000 if1_ip = ip_address(if1_ip_addr) @@ -792,7 +799,7 @@ class IPsecUtil: addr_incr = 1 << (128 - raddr_range) if if1_ip.version == 6 \ else 1 << (32 - raddr_range) - if n_tunnels > 10: + if n_tunnels - existing_tunnels > 10: tmp_fn1 = u"/tmp/ipsec_create_tunnel_dut1.config" tmp_fn2 = u"/tmp/ipsec_create_tunnel_dut2.config" if1_n = Topology.get_interface_name(nodes[u"DUT1"], if1_key) @@ -802,17 +809,20 @@ class IPsecUtil: vat = VatExecutor() with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2: rmac = Topology.get_interface_mac(nodes[u"DUT2"], if2_key) - tmp_f1.write( - f"exec create loopback interface\n" - f"exec set interface state loop0 up\n" - f"exec set interface ip address " - f"{if1_n} {if2_ip - 1}/{mask}\n" - f"exec set ip arp {if1_n} {if2_ip}/{mask2} {rmac} static\n" - ) - tmp_f2.write( - f"exec set interface ip address {if2_n} {if2_ip}/{mask}\n" - ) - for i in range(n_tunnels): + if not existing_tunnels: + tmp_f1.write( + f"exec create loopback interface\n" + f"exec set interface state loop0 up\n" + f"exec set interface ip address " + f"{if1_n} {if2_ip - 1}/{mask}\n" + f"exec set ip neighbor {if1_n} {if2_ip}/{mask2} {rmac}" + f" static\n" + ) + tmp_f2.write( + f"exec set interface ip address {if2_n}" + f" {if2_ip}/{mask}\n" + ) + for i in range(existing_tunnels, n_tunnels): ckey = gen_key( IPsecUtil.get_crypto_alg_key_len(crypto_alg) ).hex() @@ -860,10 +870,12 @@ class IPsecUtil: os.remove(tmp_fn2) with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2: - tmp_f2.write( - f"exec ip route add {if1_ip}/8 via {if2_ip - 1} {if2_n}\n" - ) - for i in range(n_tunnels): + if not existing_tunnels: + tmp_f2.write( + f"exec ip route add {if1_ip}/8 via {if2_ip - 1}" + f" {if2_n}\n" + ) + 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" @@ -890,55 +902,62 @@ class IPsecUtil: os.remove(tmp_fn2) return - with PapiSocketExecutor(nodes[u"DUT1"]) as papi_exec: - # Create loopback interface on DUT1, set it to up state - cmd1 = u"create_loopback" - args1 = dict( - mac_address=0 - ) - err_msg = f"Failed to create loopback interface " \ - f"on host {nodes[u'DUT1'][u'host']}" - loop_sw_if_idx = papi_exec.add(cmd1, **args1).\ - get_sw_if_index(err_msg) - cmd1 = u"sw_interface_set_flags" - args1 = 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(cmd1, **args1).get_reply(err_msg) - # Set IP address on VPP node 1 interface - cmd1 = u"sw_interface_add_del_address" - args1 = dict( - sw_if_index=InterfaceUtil.get_interface_index( - nodes[u"DUT1"], if1_key - ), - is_add=True, - del_all=False, - prefix=IPUtil.create_prefix_object( - if2_ip - 1, 96 if if2_ip.version == 6 else 24 + if not existing_tunnels: + with PapiSocketExecutor(nodes[u"DUT1"]) as papi_exec: + # Create loopback interface on DUT1, set it to up state + cmd1 = u"create_loopback" + args1 = dict( + mac_address=0 ) - ) - err_msg = f"Failed to set IP address on interface {if1_key} " \ - f"on host {nodes[u'DUT1'][u'host']}" - papi_exec.add(cmd1, **args1).get_reply(err_msg) - cmd4 = u"ip_neighbor_add_del" - args4 = dict( - is_add=1, - neighbor=dict( - sw_if_index=Topology.get_interface_sw_index( + err_msg = f"Failed to create loopback interface " \ + f"on host {nodes[u'DUT1'][u'host']}" + loop_sw_if_idx = papi_exec.add(cmd1, **args1).\ + get_sw_if_index(err_msg) + cmd1 = u"sw_interface_set_flags" + args1 = 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(cmd1, **args1).get_reply(err_msg) + # Set IP address on VPP node 1 interface + cmd1 = u"sw_interface_add_del_address" + args1 = dict( + sw_if_index=InterfaceUtil.get_interface_index( nodes[u"DUT1"], if1_key ), - flags=1, - mac_address=str( - Topology.get_interface_mac(nodes[u"DUT2"], if2_key) - ), - ip_address=str(ip_address(if2_ip_addr)) + is_add=True, + del_all=False, + prefix=IPUtil.create_prefix_object( + if2_ip - 1, 96 if if2_ip.version == 6 else 24 + ) ) - ) - err_msg = f"Failed to add IP neighbor on interface {if1_key}" - papi_exec.add(cmd4, **args4).get_reply(err_msg) + err_msg = f"Failed to set IP address on interface {if1_key} " \ + f"on host {nodes[u'DUT1'][u'host']}" + papi_exec.add(cmd1, **args1).get_reply(err_msg) + cmd4 = u"ip_neighbor_add_del" + args4 = dict( + is_add=1, + neighbor=dict( + sw_if_index=Topology.get_interface_sw_index( + nodes[u"DUT1"], if1_key + ), + flags=1, + mac_address=str( + Topology.get_interface_mac(nodes[u"DUT2"], if2_key) + ), + ip_address=str(ip_address(if2_ip_addr)) + ) + ) + err_msg = f"Failed to add IP neighbor on interface {if1_key}" + papi_exec.add(cmd4, **args4).get_reply(err_msg) + else: + # Executor not open, as InterfaceUtil will open its own. + loop_sw_if_idx = InterfaceUtil.vpp_get_interface_sw_index( + nodes[u"DUT1"], u"loop0") + cmd1 = u"sw_interface_add_del_address" + with PapiSocketExecutor(nodes[u"DUT1"]) as papi_exec: # Configure IPsec tunnel interfaces args1 = dict( sw_if_index=loop_sw_if_idx, @@ -948,7 +967,7 @@ class IPsecUtil: ) cmd2 = u"ipsec_tunnel_if_add_del" args2 = dict( - is_add=1, + is_add=True, local_ip=None, remote_ip=None, local_spi=0, @@ -967,10 +986,10 @@ class IPsecUtil: ) err_msg = f"Failed to add IPsec tunnel interfaces " \ f"on host {nodes[u'DUT1'][u'host']}" - ipsec_tunnels = list() - ckeys = list() - ikeys = list() - for i in range(n_tunnels): + ipsec_tunnels = [None] * existing_tunnels + ckeys = [None] * existing_tunnels + ikeys = [None] * existing_tunnels + for i in range(existing_tunnels, n_tunnels): ckeys.append( gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg)) ) @@ -983,10 +1002,10 @@ class IPsecUtil: ) args2[u"local_spi"] = spi_1 + i args2[u"remote_spi"] = spi_2 + i - args2[u"local_ip"] = IPUtil.create_ip_address_object( + args2[u"local_ip"] = IPAddress.create_ip_address_object( if1_ip + i * addr_incr ) - args2[u"remote_ip"] = IPUtil.create_ip_address_object(if2_ip) + args2[u"remote_ip"] = IPAddress.create_ip_address_object(if2_ip) args2[u"local_crypto_key_len"] = len(ckeys[i]) args2[u"local_crypto_key"] = ckeys[i] args2[u"remote_crypto_key_len"] = len(ckeys[i]) @@ -1025,7 +1044,7 @@ class IPsecUtil: ) err_msg = f"Failed to add IP routes " \ f"on host {nodes[u'DUT1'][u'host']}" - for i in range(n_tunnels): + for i in range(existing_tunnels, n_tunnels): args1[u"unnumbered_sw_if_index"] = ipsec_tunnels[i] args2[u"sw_if_index"] = ipsec_tunnels[i] args3[u"route"] = IPUtil.compose_vpp_route_structure( @@ -1040,26 +1059,27 @@ class IPsecUtil: papi_exec.get_replies(err_msg) with PapiSocketExecutor(nodes[u"DUT2"]) as papi_exec: - # Set IP address on VPP node 2 interface - cmd1 = u"sw_interface_add_del_address" - args1 = dict( - sw_if_index=InterfaceUtil.get_interface_index( - nodes[u"DUT2"], if2_key - ), - is_add=True, - del_all=False, - prefix=IPUtil.create_prefix_object( - if2_ip, 96 if if2_ip.version == 6 else 24 + if not existing_tunnels: + # Set IP address on VPP node 2 interface + cmd1 = u"sw_interface_add_del_address" + args1 = dict( + sw_if_index=InterfaceUtil.get_interface_index( + nodes[u"DUT2"], if2_key + ), + is_add=True, + del_all=False, + prefix=IPUtil.create_prefix_object( + if2_ip, 96 if if2_ip.version == 6 else 24 + ) ) - ) - err_msg = f"Failed to set IP address on interface {if2_key} " \ - f"on host {nodes[u'DUT2'][u'host']}" - papi_exec.add(cmd1, **args1).get_reply(err_msg) + err_msg = f"Failed to set IP address on interface {if2_key} " \ + f"on host {nodes[u'DUT2'][u'host']}" + papi_exec.add(cmd1, **args1).get_reply(err_msg) # Configure IPsec tunnel interfaces cmd2 = u"ipsec_tunnel_if_add_del" args2 = dict( - is_add=1, - local_ip=IPUtil.create_ip_address_object(if2_ip), + is_add=True, + local_ip=IPAddress.create_ip_address_object(if2_ip), remote_ip=None, local_spi=0, remote_spi=0, @@ -1077,12 +1097,12 @@ class IPsecUtil: ) err_msg = f"Failed to add IPsec tunnel interfaces " \ f"on host {nodes[u'DUT2'][u'host']}" - ipsec_tunnels = list() - for i in range(n_tunnels): + ipsec_tunnels = [None] * existing_tunnels + for i in range(existing_tunnels, n_tunnels): args2[u"local_spi"] = spi_2 + i args2[u"remote_spi"] = spi_1 + i - args2[u"local_ip"] = IPUtil.create_ip_address_object(if2_ip) - args2[u"remote_ip"] = IPUtil.create_ip_address_object( + args2[u"local_ip"] = IPAddress.create_ip_address_object(if2_ip) + args2[u"remote_ip"] = IPAddress.create_ip_address_object( if1_ip + i * addr_incr) args2[u"local_crypto_key_len"] = len(ckeys[i]) args2[u"local_crypto_key"] = ckeys[i] @@ -1099,20 +1119,21 @@ class IPsecUtil: for reply in replies: if u"sw_if_index" in reply: ipsec_tunnels.append(reply[u"sw_if_index"]) - # Configure IP routes - cmd1 = u"ip_route_add_del" - route = IPUtil.compose_vpp_route_structure( - nodes[u"DUT2"], if1_ip.compressed, - prefix_len=32 if if1_ip.version == 6 else 8, - interface=if2_key, - gateway=(if2_ip - 1).compressed - ) - args1 = dict( - is_add=1, - is_multipath=0, - route=route - ) - papi_exec.add(cmd1, **args1) + if not existing_tunnels: + # Configure IP routes + cmd1 = u"ip_route_add_del" + route = IPUtil.compose_vpp_route_structure( + nodes[u"DUT2"], if1_ip.compressed, + prefix_len=32 if if1_ip.version == 6 else 8, + interface=if2_key, + gateway=(if2_ip - 1).compressed + ) + args1 = dict( + is_add=1, + is_multipath=0, + route=route + ) + papi_exec.add(cmd1, **args1) cmd1 = u"sw_interface_set_unnumbered" args1 = dict( is_add=True, @@ -1134,7 +1155,7 @@ class IPsecUtil: ) err_msg = f"Failed to add IP routes " \ f"on host {nodes[u'DUT2'][u'host']}" - for i in range(n_tunnels): + for i in range(existing_tunnels, n_tunnels): args1[u"unnumbered_sw_if_index"] = ipsec_tunnels[i] args2[u"sw_if_index"] = ipsec_tunnels[i] args3[u"route"] = IPUtil.compose_vpp_route_structure( @@ -1148,6 +1169,158 @@ class IPsecUtil: add(cmd3, history=history, **args3) papi_exec.get_replies(err_msg) + @staticmethod + def _create_ipsec_script_files(dut, instances): + """Create script files for configuring IPsec in containers + + :param dut: DUT node on which to create the script files + :param instances: number of containers on DUT node + :type dut: string + :type instances: int + """ + scripts = [] + for cnf in range(0, instances): + script_filename = ( + f"/tmp/ipsec_create_tunnel_cnf_{dut}_{cnf + 1}.config" + ) + scripts.append(open(script_filename, 'w')) + return scripts + + @staticmethod + def _close_and_copy_ipsec_script_files( + dut, nodes, instances, scripts): + """Close created scripts and copy them to containers + + :param dut: DUT node on which to create the script files + :param nodes: VPP nodes + :param instances: number of containers on DUT node + :param scripts: dictionary holding the script files + :type dut: string + :type nodes: dict + :type instances: int + :type scripts: dict + """ + for cnf in range(0, instances): + scripts[cnf].close() + script_filename = ( + f"/tmp/ipsec_create_tunnel_cnf_{dut}_{cnf + 1}.config" + ) + scp_node(nodes[dut], script_filename, script_filename) + + + @staticmethod + def vpp_ipsec_create_tunnel_interfaces_in_containers( + nodes, if1_ip_addr, if2_ip_addr, if1_key, if2_key, n_tunnels, + crypto_alg, integ_alg, raddr_ip1, raddr_ip2, raddr_range, + n_instances): + """Create multiple IPsec tunnel interfaces between two VPP nodes. + + :param nodes: VPP nodes to create tunnel interfaces. + :param if1_ip_addr: VPP node 1 interface IP4 address. + :param if2_ip_addr: VPP node 2 interface IP4 address. + :param if1_key: VPP node 1 interface key from topology file. + :param if2_key: VPP node 2 interface key from topology file. + :param n_tunnels: Number of tunnell interfaces to create. + :param crypto_alg: The encryption algorithm name. + :param integ_alg: The integrity algorithm name. + :param raddr_ip1: Policy selector remote IPv4 start address for the + first tunnel in direction node1->node2. + :param raddr_ip2: Policy selector remote IPv4 start address for the + first tunnel in direction node2->node1. + :param raddr_range: Mask specifying range of Policy selector Remote + IPv4 addresses. Valid values are from 1 to 32. + :param n_instances: Number of containers. + :type nodes: dict + :type if1_ip_addr: str + :type if2_ip_addr: str + :type if1_key: str + :type if2_key: str + :type n_tunnels: int + :type crypto_alg: CryptoAlg + :type integ_alg: IntegAlg + :type raddr_ip1: string + :type raddr_ip2: string + :type raddr_range: int + :type n_instances: int + """ + spi_1 = 100000 + spi_2 = 200000 + addr_incr = 1 << (32 - raddr_range) + + dut1_scripts = IPsecUtil._create_ipsec_script_files( + u"DUT1", n_instances) + dut2_scripts = IPsecUtil._create_ipsec_script_files( + u"DUT2", n_instances) + + for cnf in range(0, n_instances): + dut1_scripts[cnf].write( + u"create loopback interface\n" + u"set interface state loop0 up\n\n" + ) + dut2_scripts[cnf].write( + f"ip route add {if1_ip_addr}/8 via " + f"{ip_address(if2_ip_addr) + cnf + 100} memif1/{cnf + 1}\n\n" + ) + + for tnl in range(0, n_tunnels): + tnl_incr = tnl * addr_incr + cnf = tnl % n_instances + i = tnl // n_instances + ckey = gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg)).hex() + integ = u"" + if integ_alg: + ikey = gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg)).hex() + integ = ( + f"integ-alg {integ_alg.alg_name} " + f"local-integ-key {ikey} " + f"remote-integ-key {ikey} " + ) + + # Configure tunnel end point(s) on left side + dut1_scripts[cnf].write( + u"set interface ip address loop0 " + f"{ip_address(if1_ip_addr) + tnl_incr}/32\n" + f"create ipsec tunnel " + f"local-ip {ip_address(if1_ip_addr) + tnl_incr} " + f"local-spi {spi_1 + tnl} " + f"remote-ip {ip_address(if2_ip_addr) + cnf} " + f"remote-spi {spi_2 + tnl} " + f"crypto-alg {crypto_alg.alg_name} " + f"local-crypto-key {ckey} " + f"remote-crypto-key {ckey} " + f"instance {i} " + f"salt 0x0 " + f"{integ} \n" + f"set interface unnumbered ipip{i} use loop0\n" + f"set interface state ipip{i} up\n" + f"ip route add {ip_address(raddr_ip2)+tnl}/32 via ipip{i}\n\n" + ) + + # Configure tunnel end point(s) on right side + dut2_scripts[cnf].write( + f"set ip neighbor memif1/{cnf + 1} " + f"{ip_address(if1_ip_addr) + tnl_incr} " + f"02:02:00:00:{17:02X}:{cnf:02X} static\n" + f"create ipsec tunnel local-ip {ip_address(if2_ip_addr) + cnf} " + f"local-spi {spi_2 + tnl} " + f"remote-ip {ip_address(if1_ip_addr) + tnl_incr} " + f"remote-spi {spi_1 + tnl} " + f"crypto-alg {crypto_alg.alg_name} " + f"local-crypto-key {ckey} " + f"remote-crypto-key {ckey} " + f"instance {i} " + f"salt 0x0 " + f"{integ}\n" + f"set interface unnumbered ipip{i} use memif1/{cnf + 1}\n" + f"set interface state ipip{i} up\n" + f"ip route add {ip_address(raddr_ip1) + tnl}/32 via ipip{i}\n\n" + ) + + IPsecUtil._close_and_copy_ipsec_script_files( + u"DUT1", nodes, n_instances, dut1_scripts) + IPsecUtil._close_and_copy_ipsec_script_files( + u"DUT2", nodes, n_instances, dut2_scripts) + @staticmethod def vpp_ipsec_add_multiple_tunnels( nodes, interface1, interface2, n_tunnels, crypto_alg, integ_alg, @@ -1166,8 +1339,8 @@ class IPsecUtil: first tunnel in direction node1->node2. :param raddr_ip2: Policy selector remote IPv4 start address for the first tunnel in direction node2->node1. - :param raddr_range: Mask specifying range of Policy selector Remote IPv4 - addresses. Valid values are from 1 to 32. + :param raddr_range: Mask specifying range of Policy selector Remote + IPv4 addresses. Valid values are from 1 to 32. :type nodes: dict :type interface1: str or int :type interface2: str or int