1 # Copyright (c) 2020 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """IPsec utilities library."""
18 from enum import Enum, IntEnum
20 from random import choice
21 from string import ascii_letters
23 from ipaddress import ip_network, ip_address
25 from resources.libraries.python.InterfaceUtil import InterfaceUtil, \
27 from resources.libraries.python.IPAddress import IPAddress
28 from resources.libraries.python.IPUtil import IPUtil
29 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
30 from resources.libraries.python.ssh import scp_node
31 from resources.libraries.python.topology import Topology
32 from resources.libraries.python.VatExecutor import VatExecutor
36 """Generate random string as a key.
38 :param length: Length of generated payload.
40 :returns: The generated payload.
44 choice(ascii_letters) for _ in range(length)
45 ).encode(encoding=u"utf-8")
48 class PolicyAction(Enum):
50 BYPASS = (u"bypass", 0)
51 DISCARD = (u"discard", 1)
52 PROTECT = (u"protect", 3)
54 def __init__(self, policy_name, policy_int_repr):
55 self.policy_name = policy_name
56 self.policy_int_repr = policy_int_repr
59 class CryptoAlg(Enum):
60 """Encryption algorithms."""
61 AES_CBC_128 = (u"aes-cbc-128", 1, u"AES-CBC", 16)
62 AES_CBC_256 = (u"aes-cbc-256", 3, u"AES-CBC", 32)
63 AES_GCM_128 = (u"aes-gcm-128", 7, u"AES-GCM", 16)
64 AES_GCM_256 = (u"aes-gcm-256", 9, u"AES-GCM", 32)
66 def __init__(self, alg_name, alg_int_repr, scapy_name, key_len):
67 self.alg_name = alg_name
68 self.alg_int_repr = alg_int_repr
69 self.scapy_name = scapy_name
70 self.key_len = key_len
74 """Integrity algorithm."""
75 SHA_256_128 = (u"sha-256-128", 4, u"SHA2-256-128", 32)
76 SHA_512_256 = (u"sha-512-256", 6, u"SHA2-512-256", 64)
78 def __init__(self, alg_name, alg_int_repr, scapy_name, key_len):
79 self.alg_name = alg_name
80 self.alg_int_repr = alg_int_repr
81 self.scapy_name = scapy_name
82 self.key_len = key_len
85 class IPsecProto(IntEnum):
87 IPSEC_API_PROTO_ESP = 50
88 IPSEC_API_PROTO_AH = 51
91 class IPsecSadFlags(IntEnum):
92 """IPsec Security Association Database flags."""
93 IPSEC_API_SAD_FLAG_NONE = 0
94 IPSEC_API_SAD_FLAG_IS_TUNNEL = 4
95 IPSEC_API_SAD_FLAG_IS_TUNNEL_V6 = 8
99 """IPsec utilities."""
102 def policy_action_bypass():
103 """Return policy action bypass.
105 :returns: PolicyAction enum BYPASS object.
108 return PolicyAction.BYPASS
111 def policy_action_discard():
112 """Return policy action discard.
114 :returns: PolicyAction enum DISCARD object.
117 return PolicyAction.DISCARD
120 def policy_action_protect():
121 """Return policy action protect.
123 :returns: PolicyAction enum PROTECT object.
126 return PolicyAction.PROTECT
129 def crypto_alg_aes_cbc_128():
130 """Return encryption algorithm aes-cbc-128.
132 :returns: CryptoAlg enum AES_CBC_128 object.
135 return CryptoAlg.AES_CBC_128
138 def crypto_alg_aes_cbc_256():
139 """Return encryption algorithm aes-cbc-256.
141 :returns: CryptoAlg enum AES_CBC_256 object.
144 return CryptoAlg.AES_CBC_256
147 def crypto_alg_aes_gcm_128():
148 """Return encryption algorithm aes-gcm-128.
150 :returns: CryptoAlg enum AES_GCM_128 object.
153 return CryptoAlg.AES_GCM_128
156 def crypto_alg_aes_gcm_256():
157 """Return encryption algorithm aes-gcm-256.
159 :returns: CryptoAlg enum AES_GCM_128 object.
162 return CryptoAlg.AES_GCM_256
165 def get_crypto_alg_key_len(crypto_alg):
166 """Return encryption algorithm key length.
168 :param crypto_alg: Encryption algorithm.
169 :type crypto_alg: CryptoAlg
170 :returns: Key length.
173 return crypto_alg.key_len
176 def get_crypto_alg_scapy_name(crypto_alg):
177 """Return encryption algorithm scapy name.
179 :param crypto_alg: Encryption algorithm.
180 :type crypto_alg: CryptoAlg
181 :returns: Algorithm scapy name.
184 return crypto_alg.scapy_name
187 def integ_alg_sha_256_128():
188 """Return integrity algorithm SHA-256-128.
190 :returns: IntegAlg enum SHA_256_128 object.
193 return IntegAlg.SHA_256_128
196 def integ_alg_sha_512_256():
197 """Return integrity algorithm SHA-512-256.
199 :returns: IntegAlg enum SHA_512_256 object.
202 return IntegAlg.SHA_512_256
205 def get_integ_alg_key_len(integ_alg):
206 """Return integrity algorithm key length.
208 :param integ_alg: Integrity algorithm.
209 :type integ_alg: IntegAlg
210 :returns: Key length.
213 return integ_alg.key_len
216 def get_integ_alg_scapy_name(integ_alg):
217 """Return integrity algorithm scapy name.
219 :param integ_alg: Integrity algorithm.
220 :type integ_alg: IntegAlg
221 :returns: Algorithm scapy name.
224 return integ_alg.scapy_name
227 def ipsec_proto_esp():
228 """Return IPSec protocol ESP.
230 :returns: IPsecProto enum ESP object.
233 return int(IPsecProto.IPSEC_API_PROTO_ESP)
236 def ipsec_proto_ah():
237 """Return IPSec protocol AH.
239 :returns: IPsecProto enum AH object.
242 return int(IPsecProto.IPSEC_API_PROTO_AH)
245 def vpp_ipsec_select_backend(node, protocol, index=1):
246 """Select IPsec backend.
248 :param node: VPP node to select IPsec backend on.
249 :param protocol: IPsec protocol.
250 :param index: Backend index.
252 :type protocol: IPsecProto
254 :raises RuntimeError: If failed to select IPsec backend or if no API
257 cmd = u"ipsec_select_backend"
258 err_msg = f"Failed to select IPsec backend on host {node[u'host']}"
263 with PapiSocketExecutor(node) as papi_exec:
264 papi_exec.add(cmd, **args).get_reply(err_msg)
267 def vpp_ipsec_add_sad_entry(
268 node, sad_id, spi, crypto_alg, crypto_key, integ_alg=None,
269 integ_key=u"", tunnel_src=None, tunnel_dst=None):
270 """Create Security Association Database entry on the VPP node.
272 :param node: VPP node to add SAD entry on.
273 :param sad_id: SAD entry ID.
274 :param spi: Security Parameter Index of this SAD entry.
275 :param crypto_alg: The encryption algorithm name.
276 :param crypto_key: The encryption key string.
277 :param integ_alg: The integrity algorithm name.
278 :param integ_key: The integrity key string.
279 :param tunnel_src: Tunnel header source IPv4 or IPv6 address. If not
280 specified ESP transport mode is used.
281 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address. If
282 not specified ESP transport mode is used.
286 :type crypto_alg: CryptoAlg
287 :type crypto_key: str
288 :type integ_alg: IntegAlg
290 :type tunnel_src: str
291 :type tunnel_dst: str
293 if isinstance(crypto_key, str):
294 crypto_key = crypto_key.encode(encoding=u"utf-8")
295 if isinstance(integ_key, str):
296 integ_key = integ_key.encode(encoding=u"utf-8")
298 length=len(crypto_key),
302 length=len(integ_key),
303 data=integ_key if integ_key else 0
306 flags = int(IPsecSadFlags.IPSEC_API_SAD_FLAG_NONE)
307 if tunnel_src and tunnel_dst:
308 flags = flags | int(IPsecSadFlags.IPSEC_API_SAD_FLAG_IS_TUNNEL)
309 src_addr = ip_address(tunnel_src)
310 dst_addr = ip_address(tunnel_dst)
311 if src_addr.version == 6:
313 flags | int(IPsecSadFlags.IPSEC_API_SAD_FLAG_IS_TUNNEL_V6)
318 cmd = u"ipsec_sad_entry_add_del"
319 err_msg = f"Failed to add Security Association Database entry " \
320 f"on host {node[u'host']}"
324 crypto_algorithm=crypto_alg.alg_int_repr,
326 integrity_algorithm=integ_alg.alg_int_repr if integ_alg else 0,
329 tunnel_src=str(src_addr),
330 tunnel_dst=str(dst_addr),
331 protocol=int(IPsecProto.IPSEC_API_PROTO_ESP)
337 with PapiSocketExecutor(node) as papi_exec:
338 papi_exec.add(cmd, **args).get_reply(err_msg)
341 def vpp_ipsec_add_sad_entries(
342 node, n_entries, sad_id, spi, crypto_alg, crypto_key,
343 integ_alg=None, integ_key=u"", tunnel_src=None, tunnel_dst=None):
344 """Create multiple Security Association Database entries on VPP node.
346 :param node: VPP node to add SAD entry on.
347 :param n_entries: Number of SAD entries to be created.
348 :param sad_id: First SAD entry ID. All subsequent SAD entries will have
350 :param spi: Security Parameter Index of first SAD entry. All subsequent
351 SAD entries will have spi incremented by 1.
352 :param crypto_alg: The encryption algorithm name.
353 :param crypto_key: The encryption key string.
354 :param integ_alg: The integrity algorithm name.
355 :param integ_key: The integrity key string.
356 :param tunnel_src: Tunnel header source IPv4 or IPv6 address. If not
357 specified ESP transport mode is used.
358 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address. If
359 not specified ESP transport mode is used.
364 :type crypto_alg: CryptoAlg
365 :type crypto_key: str
366 :type integ_alg: IntegAlg
368 :type tunnel_src: str
369 :type tunnel_dst: str
371 if isinstance(crypto_key, str):
372 crypto_key = crypto_key.encode(encoding=u"utf-8")
373 if isinstance(integ_key, str):
374 integ_key = integ_key.encode(encoding=u"utf-8")
375 if tunnel_src and tunnel_dst:
376 src_addr = ip_address(tunnel_src)
377 dst_addr = ip_address(tunnel_dst)
382 addr_incr = 1 << (128 - 96) if src_addr.version == 6 \
385 if int(n_entries) > 10:
386 tmp_filename = f"/tmp/ipsec_sad_{sad_id}_add_del_entry.script"
388 with open(tmp_filename, 'w') as tmp_file:
389 for i in range(n_entries):
390 integ = f"integ-alg {integ_alg.alg_name} " \
391 f"integ-key {integ_key.hex()}" \
392 if integ_alg else u""
393 tunnel = f"tunnel-src {src_addr + i * addr_incr} " \
394 f"tunnel-dst {dst_addr + i * addr_incr}" \
395 if tunnel_src and tunnel_dst else u""
396 conf = f"exec ipsec sa add {sad_id + i} esp spi {spi + i} "\
397 f"crypto-alg {crypto_alg.alg_name} " \
398 f"crypto-key {crypto_key.hex()} " \
399 f"{integ} {tunnel}\n"
403 tmp_filename, node, timeout=300, json_out=False,
406 os.remove(tmp_filename)
410 length=len(crypto_key),
414 length=len(integ_key),
415 data=integ_key if integ_key else 0
418 flags = int(IPsecSadFlags.IPSEC_API_SAD_FLAG_NONE)
419 if tunnel_src and tunnel_dst:
420 flags = flags | int(IPsecSadFlags.IPSEC_API_SAD_FLAG_IS_TUNNEL)
421 if src_addr.version == 6:
423 IPsecSadFlags.IPSEC_API_SAD_FLAG_IS_TUNNEL_V6
426 cmd = u"ipsec_sad_entry_add_del"
427 err_msg = f"Failed to add Security Association Database entry " \
428 f"on host {node[u'host']}"
433 crypto_algorithm=crypto_alg.alg_int_repr,
435 integrity_algorithm=integ_alg.alg_int_repr if integ_alg else 0,
438 tunnel_src=str(src_addr),
439 tunnel_dst=str(dst_addr),
440 protocol=int(IPsecProto.IPSEC_API_PROTO_ESP)
446 with PapiSocketExecutor(node) as papi_exec:
447 for i in range(n_entries):
448 args[u"entry"][u"sad_id"] = int(sad_id) + i
449 args[u"entry"][u"spi"] = int(spi) + i
450 args[u"entry"][u"tunnel_src"] = str(src_addr + i * addr_incr) \
451 if tunnel_src and tunnel_dst else src_addr
452 args[u"entry"][u"tunnel_dst"] = str(dst_addr + i * addr_incr) \
453 if tunnel_src and tunnel_dst else dst_addr
454 history = bool(not 1 < i < n_entries - 2)
455 papi_exec.add(cmd, history=history, **args)
456 papi_exec.get_replies(err_msg)
459 def vpp_ipsec_set_ip_route(
460 node, n_tunnels, tunnel_src, traffic_addr, tunnel_dst, interface,
462 """Set IP address and route on interface.
464 :param node: VPP node to add config on.
465 :param n_tunnels: Number of tunnels to create.
466 :param tunnel_src: Tunnel header source IPv4 or IPv6 address.
467 :param traffic_addr: Traffic destination IP address to route.
468 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address.
469 :param interface: Interface key on node 1.
470 :param raddr_range: Mask specifying range of Policy selector Remote IP
471 addresses. Valid values are from 1 to 32 in case of IPv4 and to 128
475 :type tunnel_src: str
476 :type traffic_addr: str
477 :type tunnel_dst: str
479 :type raddr_range: int
481 laddr = ip_address(tunnel_src)
482 raddr = ip_address(tunnel_dst)
483 taddr = ip_address(traffic_addr)
484 addr_incr = 1 << (128 - raddr_range) if laddr.version == 6 \
485 else 1 << (32 - raddr_range)
487 if int(n_tunnels) > 10:
488 tmp_filename = u"/tmp/ipsec_set_ip.script"
490 with open(tmp_filename, 'w') as tmp_file:
491 if_name = Topology.get_interface_name(node, interface)
492 for i in range(n_tunnels):
493 conf = f"exec set interface ip address {if_name} " \
494 f"{laddr + i * addr_incr}/{raddr_range}\n" \
495 f"exec ip route add {taddr + i}/" \
496 f"{128 if taddr.version == 6 else 32} " \
497 f"via {raddr + i * addr_incr} {if_name}\n"
501 tmp_filename, node, timeout=300, json_out=False,
504 os.remove(tmp_filename)
507 cmd1 = u"sw_interface_add_del_address"
509 sw_if_index=InterfaceUtil.get_interface_index(node, interface),
514 cmd2 = u"ip_route_add_del"
520 err_msg = f"Failed to configure IP addresses and IP routes " \
521 f"on interface {interface} on host {node[u'host']}"
523 with PapiSocketExecutor(node) as papi_exec:
524 for i in range(n_tunnels):
525 args1[u"prefix"] = IPUtil.create_prefix_object(
526 laddr + i * addr_incr, raddr_range
528 args2[u"route"] = IPUtil.compose_vpp_route_structure(
530 prefix_len=128 if taddr.version == 6 else 32,
531 interface=interface, gateway=raddr + i * addr_incr
533 history = bool(not 1 < i < n_tunnels - 2)
534 papi_exec.add(cmd1, history=history, **args1).\
535 add(cmd2, history=history, **args2)
536 papi_exec.get_replies(err_msg)
539 def vpp_ipsec_add_spd(node, spd_id):
540 """Create Security Policy Database on the VPP node.
542 :param node: VPP node to add SPD on.
543 :param spd_id: SPD ID.
547 cmd = u"ipsec_spd_add_del"
548 err_msg = f"Failed to add Security Policy Database " \
549 f"on host {node[u'host']}"
554 with PapiSocketExecutor(node) as papi_exec:
555 papi_exec.add(cmd, **args).get_reply(err_msg)
558 def vpp_ipsec_spd_add_if(node, spd_id, interface):
559 """Add interface to the Security Policy Database.
561 :param node: VPP node.
562 :param spd_id: SPD ID to add interface on.
563 :param interface: Interface name or sw_if_index.
566 :type interface: str or int
568 cmd = u"ipsec_interface_add_del_spd"
569 err_msg = f"Failed to add interface {interface} to Security Policy " \
570 f"Database {spd_id} on host {node[u'host']}"
573 sw_if_index=InterfaceUtil.get_interface_index(node, interface),
576 with PapiSocketExecutor(node) as papi_exec:
577 papi_exec.add(cmd, **args).get_reply(err_msg)
580 def vpp_ipsec_policy_add(
581 node, spd_id, priority, action, inbound=True, sa_id=None,
582 laddr_range=None, raddr_range=None, proto=None, lport_range=None,
583 rport_range=None, is_ipv6=False):
584 """Create Security Policy Database entry on the VPP node.
586 :param node: VPP node to add SPD entry on.
587 :param spd_id: SPD ID to add entry on.
588 :param priority: SPD entry priority, higher number = higher priority.
589 :param action: Policy action.
590 :param inbound: If True policy is for inbound traffic, otherwise
592 :param sa_id: SAD entry ID for protect action.
593 :param laddr_range: Policy selector local IPv4 or IPv6 address range in
594 format IP/prefix or IP/mask. If no mask is provided,
595 it's considered to be /32.
596 :param raddr_range: Policy selector remote IPv4 or IPv6 address range in
597 format IP/prefix or IP/mask. If no mask is provided,
598 it's considered to be /32.
599 :param proto: Policy selector next layer protocol number.
600 :param lport_range: Policy selector local TCP/UDP port range in format
601 <port_start>-<port_end>.
602 :param rport_range: Policy selector remote TCP/UDP port range in format
603 <port_start>-<port_end>.
604 :param is_ipv6: True in case of IPv6 policy when IPv6 address range is
605 not defined so it will default to address ::/0, otherwise False.
609 :type action: PolicyAction
612 :type laddr_range: string
613 :type raddr_range: string
615 :type lport_range: string
616 :type rport_range: string
619 if laddr_range is None:
620 laddr_range = u"::/0" if is_ipv6 else u"0.0.0.0/0"
622 if raddr_range is None:
623 raddr_range = u"::/0" if is_ipv6 else u"0.0.0.0/0"
625 cmd = u"ipsec_spd_entry_add_del"
626 err_msg = f"Failed to add entry to Security Policy Database {spd_id} " \
627 f"on host {node[u'host']}"
631 priority=int(priority),
632 is_outbound=not inbound,
633 sa_id=int(sa_id) if sa_id else 0,
634 policy=action.policy_int_repr,
635 protocol=int(proto) if proto else 0,
636 remote_address_start=IPAddress.create_ip_address_object(
637 ip_network(raddr_range, strict=False).network_address
639 remote_address_stop=IPAddress.create_ip_address_object(
640 ip_network(raddr_range, strict=False).broadcast_address
642 local_address_start=IPAddress.create_ip_address_object(
643 ip_network(laddr_range, strict=False).network_address
645 local_address_stop=IPAddress.create_ip_address_object(
646 ip_network(laddr_range, strict=False).broadcast_address
648 remote_port_start=int(rport_range.split(u"-")[0]) if rport_range
650 remote_port_stop=int(rport_range.split(u"-")[1]) if rport_range
652 local_port_start=int(lport_range.split(u"-")[0]) if lport_range
654 local_port_stop=int(lport_range.split(u"-")[1]) if rport_range
661 with PapiSocketExecutor(node) as papi_exec:
662 papi_exec.add(cmd, **args).get_reply(err_msg)
665 def vpp_ipsec_spd_add_entries(
666 node, n_entries, spd_id, priority, inbound, sa_id, raddr_ip,
668 """Create multiple Security Policy Database entries on the VPP node.
670 :param node: VPP node to add SPD entries on.
671 :param n_entries: Number of SPD entries to be added.
672 :param spd_id: SPD ID to add entries on.
673 :param priority: SPD entries priority, higher number = higher priority.
674 :param inbound: If True policy is for inbound traffic, otherwise
676 :param sa_id: SAD entry ID for first entry. Each subsequent entry will
677 SAD entry ID incremented by 1.
678 :param raddr_ip: Policy selector remote IPv4 start address for the first
679 entry. Remote IPv4 end address will be calculated depending on
680 raddr_range parameter. Each subsequent entry will have start address
681 next after IPv4 end address of previous entry.
682 :param raddr_range: Required IP addres range.
690 :type raddr_range: int
692 raddr_ip = ip_address(raddr_ip)
693 if int(n_entries) > 10:
694 tmp_filename = f"/tmp/ipsec_spd_{sa_id}_add_del_entry.script"
696 with open(tmp_filename, 'w') as tmp_file:
697 for i in range(n_entries):
698 direction = u'inbound' if inbound else u'outbound'
699 tunnel = f"exec ipsec policy add spd {spd_id} " \
700 f"priority {priority} {direction} " \
701 f"action protect sa {sa_id+i} " \
702 f"remote-ip-range {raddr_ip + i * (raddr_range + 1)} " \
703 f"- {raddr_ip + (i + 1) * raddr_range + i} " \
704 f"local-ip-range 0.0.0.0 - 255.255.255.255\n"
705 tmp_file.write(tunnel)
706 VatExecutor().execute_script(
707 tmp_filename, node, timeout=300, json_out=False,
710 os.remove(tmp_filename)
713 laddr_range = u"::/0" if raddr_ip.version == 6 else u"0.0.0.0/0"
715 cmd = u"ipsec_spd_entry_add_del"
716 err_msg = f"ailed to add entry to Security Policy Database '{spd_id} " \
717 f"on host {node[u'host']}"
721 priority=int(priority),
722 is_outbound=not inbound,
723 sa_id=int(sa_id) if sa_id else 0,
724 policy=IPsecUtil.policy_action_protect().policy_int_repr,
726 remote_address_start=IPAddress.create_ip_address_object(raddr_ip),
727 remote_address_stop=IPAddress.create_ip_address_object(raddr_ip),
728 local_address_start=IPAddress.create_ip_address_object(
729 ip_network(laddr_range, strict=False).network_address
731 local_address_stop=IPAddress.create_ip_address_object(
732 ip_network(laddr_range, strict=False).broadcast_address
735 remote_port_stop=65535,
737 local_port_stop=65535
744 with PapiSocketExecutor(node) as papi_exec:
745 for i in range(n_entries):
746 args[u"entry"][u"remote_address_start"][u"un"] = \
747 IPAddress.union_addr(raddr_ip + i)
748 args[u"entry"][u"remote_address_stop"][u"un"] = \
749 IPAddress.union_addr(raddr_ip + i)
750 history = bool(not 1 < i < n_entries - 2)
751 papi_exec.add(cmd, history=history, **args)
752 papi_exec.get_replies(err_msg)
755 def vpp_ipsec_create_tunnel_interfaces(
756 nodes, if1_ip_addr, if2_ip_addr, if1_key, if2_key, n_tunnels,
757 crypto_alg, integ_alg, raddr_ip1, raddr_ip2, raddr_range,
759 """Create multiple IPsec tunnel interfaces between two VPP nodes.
761 :param nodes: VPP nodes to create tunnel interfaces.
762 :param if1_ip_addr: VPP node 1 interface IPv4/IPv6 address.
763 :param if2_ip_addr: VPP node 2 interface IPv4/IPv6 address.
764 :param if1_key: VPP node 1 interface key from topology file.
765 :param if2_key: VPP node 2 interface key from topology file.
766 :param n_tunnels: Number of tunnel interfaces to be there at the end.
767 :param crypto_alg: The encryption algorithm name.
768 :param integ_alg: The integrity algorithm name.
769 :param raddr_ip1: Policy selector remote IPv4/IPv6 start address for the
770 first tunnel in direction node1->node2.
771 :param raddr_ip2: Policy selector remote IPv4/IPv6 start address for the
772 first tunnel in direction node2->node1.
773 :param raddr_range: Mask specifying range of Policy selector Remote
774 IPv4/IPv6 addresses. Valid values are from 1 to 32 in case of IPv4
775 and to 128 in case of IPv6.
776 :param existing_tunnels: Number of tunnel interfaces before creation.
777 Useful mainly for reconf tests. Default 0.
779 :type if1_ip_addr: str
780 :type if2_ip_addr: str
784 :type crypto_alg: CryptoAlg
785 :type integ_alg: IntegAlg
786 :type raddr_ip1: string
787 :type raddr_ip2: string
788 :type raddr_range: int
789 :type existing_tunnels: int
791 n_tunnels = int(n_tunnels)
792 existing_tunnels = int(existing_tunnels)
795 if1_ip = ip_address(if1_ip_addr)
796 if2_ip = ip_address(if2_ip_addr)
797 raddr_ip1 = ip_address(raddr_ip1)
798 raddr_ip2 = ip_address(raddr_ip2)
799 addr_incr = 1 << (128 - raddr_range) if if1_ip.version == 6 \
800 else 1 << (32 - raddr_range)
802 if n_tunnels - existing_tunnels > 10:
803 tmp_fn1 = u"/tmp/ipsec_create_tunnel_dut1.config"
804 tmp_fn2 = u"/tmp/ipsec_create_tunnel_dut2.config"
805 if1_n = Topology.get_interface_name(nodes[u"DUT1"], if1_key)
806 if2_n = Topology.get_interface_name(nodes[u"DUT2"], if2_key)
807 mask = 96 if if2_ip.version == 6 else 24
808 mask2 = 128 if if2_ip.version == 6 else 32
810 with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2:
811 rmac = Topology.get_interface_mac(nodes[u"DUT2"], if2_key)
812 if not existing_tunnels:
814 f"exec create loopback interface\n"
815 f"exec set interface state loop0 up\n"
816 f"exec set interface ip address "
817 f"{if1_n} {if2_ip - 1}/{mask}\n"
818 f"exec set ip neighbor {if1_n} {if2_ip}/{mask2} {rmac}"
822 f"exec set interface ip address {if2_n}"
823 f" {if2_ip}/{mask}\n"
825 for i in range(existing_tunnels, n_tunnels):
827 IPsecUtil.get_crypto_alg_key_len(crypto_alg)
831 IPsecUtil.get_integ_alg_key_len(integ_alg)
833 integ = f"integ_alg {integ_alg.alg_name} " \
834 f"local_integ_key {ikey} remote_integ_key {ikey} "
838 f"exec set interface ip address loop0 "
839 f"{if1_ip + i * addr_incr}/32\n"
840 f"ipsec_tunnel_if_add_del "
841 f"local_spi {spi_1 + i} remote_spi {spi_2 + i} "
842 f"crypto_alg {crypto_alg.alg_name} "
843 f"local_crypto_key {ckey} remote_crypto_key {ckey} "
845 f"local_ip {if1_ip + i * addr_incr} "
846 f"remote_ip {if2_ip} "
850 f"ipsec_tunnel_if_add_del "
851 f"local_spi {spi_2 + i} remote_spi {spi_1 + i} "
852 f"crypto_alg {crypto_alg.alg_name} "
853 f"local_crypto_key {ckey} remote_crypto_key {ckey} "
855 f"local_ip {if2_ip} "
856 f"remote_ip {if1_ip + i * addr_incr} "
860 tmp_fn1, nodes[u"DUT1"], timeout=1800, json_out=False,
861 copy_on_execute=True,
862 history=bool(n_tunnels < 100)
865 tmp_fn2, nodes[u"DUT2"], timeout=1800, json_out=False,
866 copy_on_execute=True,
867 history=bool(n_tunnels < 100)
872 with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2:
873 if not existing_tunnels:
875 f"exec ip route add {if1_ip}/8 via {if2_ip - 1}"
878 for i in range(existing_tunnels, n_tunnels):
880 f"exec set interface unnumbered ipip{i} use {if1_n}\n"
881 f"exec set interface state ipip{i} up\n"
882 f"exec ip route add {raddr_ip2 + i}/{mask2} "
886 f"exec set interface unnumbered ipip{i} use {if2_n}\n"
887 f"exec set interface state ipip{i} up\n"
888 f"exec ip route add {raddr_ip1 + i}/{mask2} "
892 tmp_fn1, nodes[u"DUT1"], timeout=1800, json_out=False,
893 copy_on_execute=True,
894 history=bool(n_tunnels < 100)
897 tmp_fn2, nodes[u"DUT2"], timeout=1800, json_out=False,
898 copy_on_execute=True,
899 history=bool(n_tunnels < 100)
905 if not existing_tunnels:
906 with PapiSocketExecutor(nodes[u"DUT1"]) as papi_exec:
907 # Create loopback interface on DUT1, set it to up state
908 cmd1 = u"create_loopback"
912 err_msg = f"Failed to create loopback interface " \
913 f"on host {nodes[u'DUT1'][u'host']}"
914 loop_sw_if_idx = papi_exec.add(cmd1, **args1).\
915 get_sw_if_index(err_msg)
916 cmd1 = u"sw_interface_set_flags"
918 sw_if_index=loop_sw_if_idx,
919 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
921 err_msg = f"Failed to set loopback interface state up " \
922 f"on host {nodes[u'DUT1'][u'host']}"
923 papi_exec.add(cmd1, **args1).get_reply(err_msg)
924 # Set IP address on VPP node 1 interface
925 cmd1 = u"sw_interface_add_del_address"
927 sw_if_index=InterfaceUtil.get_interface_index(
928 nodes[u"DUT1"], if1_key
932 prefix=IPUtil.create_prefix_object(
933 if2_ip - 1, 96 if if2_ip.version == 6 else 24
936 err_msg = f"Failed to set IP address on interface {if1_key} " \
937 f"on host {nodes[u'DUT1'][u'host']}"
938 papi_exec.add(cmd1, **args1).get_reply(err_msg)
939 cmd4 = u"ip_neighbor_add_del"
943 sw_if_index=Topology.get_interface_sw_index(
944 nodes[u"DUT1"], if1_key
948 Topology.get_interface_mac(nodes[u"DUT2"], if2_key)
950 ip_address=str(ip_address(if2_ip_addr))
953 err_msg = f"Failed to add IP neighbor on interface {if1_key}"
954 papi_exec.add(cmd4, **args4).get_reply(err_msg)
956 # Executor not open, as InterfaceUtil will open its own.
957 loop_sw_if_idx = InterfaceUtil.vpp_get_interface_sw_index(
958 nodes[u"DUT1"], u"loop0")
959 cmd1 = u"sw_interface_add_del_address"
960 with PapiSocketExecutor(nodes[u"DUT1"]) as papi_exec:
961 # Configure IPsec tunnel interfaces
963 sw_if_index=loop_sw_if_idx,
968 cmd2 = u"ipsec_tunnel_if_add_del"
975 crypto_alg=crypto_alg.alg_int_repr,
976 local_crypto_key_len=0,
977 local_crypto_key=None,
978 remote_crypto_key_len=0,
979 remote_crypto_key=None,
980 integ_alg=integ_alg.alg_int_repr if integ_alg else 0,
981 local_integ_key_len=0,
982 local_integ_key=None,
983 remote_integ_key_len=0,
984 remote_integ_key=None,
987 err_msg = f"Failed to add IPsec tunnel interfaces " \
988 f"on host {nodes[u'DUT1'][u'host']}"
989 ipsec_tunnels = [None] * existing_tunnels
990 ckeys = [None] * existing_tunnels
991 ikeys = [None] * existing_tunnels
992 for i in range(existing_tunnels, n_tunnels):
994 gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
998 gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
1000 args1[u"prefix"] = IPUtil.create_prefix_object(
1001 if1_ip + i * addr_incr, 128 if if1_ip.version == 6 else 32
1003 args2[u"local_spi"] = spi_1 + i
1004 args2[u"remote_spi"] = spi_2 + i
1005 args2[u"local_ip"] = IPAddress.create_ip_address_object(
1006 if1_ip + i * addr_incr
1008 args2[u"remote_ip"] = IPAddress.create_ip_address_object(if2_ip)
1009 args2[u"local_crypto_key_len"] = len(ckeys[i])
1010 args2[u"local_crypto_key"] = ckeys[i]
1011 args2[u"remote_crypto_key_len"] = len(ckeys[i])
1012 args2[u"remote_crypto_key"] = ckeys[i]
1014 args2[u"local_integ_key_len"] = len(ikeys[i])
1015 args2[u"local_integ_key"] = ikeys[i]
1016 args2[u"remote_integ_key_len"] = len(ikeys[i])
1017 args2[u"remote_integ_key"] = ikeys[i]
1018 history = bool(not 1 < i < n_tunnels - 2)
1019 papi_exec.add(cmd1, history=history, **args1).\
1020 add(cmd2, history=history, **args2)
1021 replies = papi_exec.get_replies(err_msg)
1022 for reply in replies:
1023 if u"sw_if_index" in reply:
1024 ipsec_tunnels.append(reply[u"sw_if_index"])
1025 # Configure IP routes
1026 cmd1 = u"sw_interface_set_unnumbered"
1029 sw_if_index=InterfaceUtil.get_interface_index(
1030 nodes[u"DUT1"], if1_key
1032 unnumbered_sw_if_index=0
1034 cmd2 = u"sw_interface_set_flags"
1037 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
1039 cmd3 = u"ip_route_add_del"
1045 err_msg = f"Failed to add IP routes " \
1046 f"on host {nodes[u'DUT1'][u'host']}"
1047 for i in range(existing_tunnels, n_tunnels):
1048 args1[u"unnumbered_sw_if_index"] = ipsec_tunnels[i]
1049 args2[u"sw_if_index"] = ipsec_tunnels[i]
1050 args3[u"route"] = IPUtil.compose_vpp_route_structure(
1051 nodes[u"DUT1"], (raddr_ip2 + i).compressed,
1052 prefix_len=128 if raddr_ip2.version == 6 else 32,
1053 interface=ipsec_tunnels[i]
1055 history = bool(not 1 < i < n_tunnels - 2)
1056 papi_exec.add(cmd1, history=history, **args1).\
1057 add(cmd2, history=history, **args2).\
1058 add(cmd3, history=history, **args3)
1059 papi_exec.get_replies(err_msg)
1061 with PapiSocketExecutor(nodes[u"DUT2"]) as papi_exec:
1062 if not existing_tunnels:
1063 # Set IP address on VPP node 2 interface
1064 cmd1 = u"sw_interface_add_del_address"
1066 sw_if_index=InterfaceUtil.get_interface_index(
1067 nodes[u"DUT2"], if2_key
1071 prefix=IPUtil.create_prefix_object(
1072 if2_ip, 96 if if2_ip.version == 6 else 24
1075 err_msg = f"Failed to set IP address on interface {if2_key} " \
1076 f"on host {nodes[u'DUT2'][u'host']}"
1077 papi_exec.add(cmd1, **args1).get_reply(err_msg)
1078 # Configure IPsec tunnel interfaces
1079 cmd2 = u"ipsec_tunnel_if_add_del"
1082 local_ip=IPAddress.create_ip_address_object(if2_ip),
1086 crypto_alg=crypto_alg.alg_int_repr,
1087 local_crypto_key_len=0,
1088 local_crypto_key=None,
1089 remote_crypto_key_len=0,
1090 remote_crypto_key=None,
1091 integ_alg=integ_alg.alg_int_repr if integ_alg else 0,
1092 local_integ_key_len=0,
1093 local_integ_key=None,
1094 remote_integ_key_len=0,
1095 remote_integ_key=None,
1098 err_msg = f"Failed to add IPsec tunnel interfaces " \
1099 f"on host {nodes[u'DUT2'][u'host']}"
1100 ipsec_tunnels = [None] * existing_tunnels
1101 for i in range(existing_tunnels, n_tunnels):
1102 args2[u"local_spi"] = spi_2 + i
1103 args2[u"remote_spi"] = spi_1 + i
1104 args2[u"local_ip"] = IPAddress.create_ip_address_object(if2_ip)
1105 args2[u"remote_ip"] = IPAddress.create_ip_address_object(
1106 if1_ip + i * addr_incr)
1107 args2[u"local_crypto_key_len"] = len(ckeys[i])
1108 args2[u"local_crypto_key"] = ckeys[i]
1109 args2[u"remote_crypto_key_len"] = len(ckeys[i])
1110 args2[u"remote_crypto_key"] = ckeys[i]
1112 args2[u"local_integ_key_len"] = len(ikeys[i])
1113 args2[u"local_integ_key"] = ikeys[i]
1114 args2[u"remote_integ_key_len"] = len(ikeys[i])
1115 args2[u"remote_integ_key"] = ikeys[i]
1116 history = bool(not 1 < i < n_tunnels - 2)
1117 papi_exec.add(cmd2, history=history, **args2)
1118 replies = papi_exec.get_replies(err_msg)
1119 for reply in replies:
1120 if u"sw_if_index" in reply:
1121 ipsec_tunnels.append(reply[u"sw_if_index"])
1122 if not existing_tunnels:
1123 # Configure IP routes
1124 cmd1 = u"ip_route_add_del"
1125 route = IPUtil.compose_vpp_route_structure(
1126 nodes[u"DUT2"], if1_ip.compressed,
1127 prefix_len=32 if if1_ip.version == 6 else 8,
1129 gateway=(if2_ip - 1).compressed
1136 papi_exec.add(cmd1, **args1)
1137 cmd1 = u"sw_interface_set_unnumbered"
1140 sw_if_index=InterfaceUtil.get_interface_index(
1141 nodes[u"DUT2"], if2_key
1143 unnumbered_sw_if_index=0
1145 cmd2 = u"sw_interface_set_flags"
1148 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
1150 cmd3 = u"ip_route_add_del"
1156 err_msg = f"Failed to add IP routes " \
1157 f"on host {nodes[u'DUT2'][u'host']}"
1158 for i in range(existing_tunnels, n_tunnels):
1159 args1[u"unnumbered_sw_if_index"] = ipsec_tunnels[i]
1160 args2[u"sw_if_index"] = ipsec_tunnels[i]
1161 args3[u"route"] = IPUtil.compose_vpp_route_structure(
1162 nodes[u"DUT1"], (raddr_ip1 + i).compressed,
1163 prefix_len=128 if raddr_ip1.version == 6 else 32,
1164 interface=ipsec_tunnels[i]
1166 history = bool(not 1 < i < n_tunnels - 2)
1167 papi_exec.add(cmd1, history=history, **args1). \
1168 add(cmd2, history=history, **args2). \
1169 add(cmd3, history=history, **args3)
1170 papi_exec.get_replies(err_msg)
1173 def _create_ipsec_script_files(dut, instances):
1174 """Create script files for configuring IPsec in containers
1176 :param dut: DUT node on which to create the script files
1177 :param instances: number of containers on DUT node
1179 :type instances: int
1182 for cnf in range(0, instances):
1184 f"/tmp/ipsec_create_tunnel_cnf_{dut}_{cnf + 1}.config"
1186 scripts.append(open(script_filename, 'w'))
1190 def _close_and_copy_ipsec_script_files(
1191 dut, nodes, instances, scripts):
1192 """Close created scripts and copy them to containers
1194 :param dut: DUT node on which to create the script files
1195 :param nodes: VPP nodes
1196 :param instances: number of containers on DUT node
1197 :param scripts: dictionary holding the script files
1200 :type instances: int
1203 for cnf in range(0, instances):
1204 scripts[cnf].close()
1206 f"/tmp/ipsec_create_tunnel_cnf_{dut}_{cnf + 1}.config"
1208 scp_node(nodes[dut], script_filename, script_filename)
1212 def vpp_ipsec_create_tunnel_interfaces_in_containers(
1213 nodes, if1_ip_addr, if2_ip_addr, if1_key, if2_key, n_tunnels,
1214 crypto_alg, integ_alg, raddr_ip1, raddr_ip2, raddr_range,
1216 """Create multiple IPsec tunnel interfaces between two VPP nodes.
1218 :param nodes: VPP nodes to create tunnel interfaces.
1219 :param if1_ip_addr: VPP node 1 interface IP4 address.
1220 :param if2_ip_addr: VPP node 2 interface IP4 address.
1221 :param if1_key: VPP node 1 interface key from topology file.
1222 :param if2_key: VPP node 2 interface key from topology file.
1223 :param n_tunnels: Number of tunnell interfaces to create.
1224 :param crypto_alg: The encryption algorithm name.
1225 :param integ_alg: The integrity algorithm name.
1226 :param raddr_ip1: Policy selector remote IPv4 start address for the
1227 first tunnel in direction node1->node2.
1228 :param raddr_ip2: Policy selector remote IPv4 start address for the
1229 first tunnel in direction node2->node1.
1230 :param raddr_range: Mask specifying range of Policy selector Remote
1231 IPv4 addresses. Valid values are from 1 to 32.
1232 :param n_instances: Number of containers.
1234 :type if1_ip_addr: str
1235 :type if2_ip_addr: str
1238 :type n_tunnels: int
1239 :type crypto_alg: CryptoAlg
1240 :type integ_alg: IntegAlg
1241 :type raddr_ip1: string
1242 :type raddr_ip2: string
1243 :type raddr_range: int
1244 :type n_instances: int
1248 addr_incr = 1 << (32 - raddr_range)
1250 dut1_scripts = IPsecUtil._create_ipsec_script_files(
1251 u"DUT1", n_instances)
1252 dut2_scripts = IPsecUtil._create_ipsec_script_files(
1253 u"DUT2", n_instances)
1255 for cnf in range(0, n_instances):
1256 dut1_scripts[cnf].write(
1257 u"create loopback interface\n"
1258 u"set interface state loop0 up\n\n"
1260 dut2_scripts[cnf].write(
1261 f"ip route add {if1_ip_addr}/8 via "
1262 f"{ip_address(if2_ip_addr) + cnf + 100} memif1/{cnf + 1}\n\n"
1265 for tnl in range(0, n_tunnels):
1266 tnl_incr = tnl * addr_incr
1267 cnf = tnl % n_instances
1268 i = tnl // n_instances
1269 ckey = gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg)).hex()
1272 ikey = gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg)).hex()
1274 f"integ-alg {integ_alg.alg_name} "
1275 f"local-integ-key {ikey} "
1276 f"remote-integ-key {ikey} "
1279 # Configure tunnel end point(s) on left side
1280 dut1_scripts[cnf].write(
1281 u"set interface ip address loop0 "
1282 f"{ip_address(if1_ip_addr) + tnl_incr}/32\n"
1283 f"create ipsec tunnel "
1284 f"local-ip {ip_address(if1_ip_addr) + tnl_incr} "
1285 f"local-spi {spi_1 + tnl} "
1286 f"remote-ip {ip_address(if2_ip_addr) + cnf} "
1287 f"remote-spi {spi_2 + tnl} "
1288 f"crypto-alg {crypto_alg.alg_name} "
1289 f"local-crypto-key {ckey} "
1290 f"remote-crypto-key {ckey} "
1294 f"set interface unnumbered ipip{i} use loop0\n"
1295 f"set interface state ipip{i} up\n"
1296 f"ip route add {ip_address(raddr_ip2)+tnl}/32 via ipip{i}\n\n"
1299 # Configure tunnel end point(s) on right side
1300 dut2_scripts[cnf].write(
1301 f"set ip neighbor memif1/{cnf + 1} "
1302 f"{ip_address(if1_ip_addr) + tnl_incr} "
1303 f"02:02:00:00:{17:02X}:{cnf:02X} static\n"
1304 f"create ipsec tunnel local-ip {ip_address(if2_ip_addr) + cnf} "
1305 f"local-spi {spi_2 + tnl} "
1306 f"remote-ip {ip_address(if1_ip_addr) + tnl_incr} "
1307 f"remote-spi {spi_1 + tnl} "
1308 f"crypto-alg {crypto_alg.alg_name} "
1309 f"local-crypto-key {ckey} "
1310 f"remote-crypto-key {ckey} "
1314 f"set interface unnumbered ipip{i} use memif1/{cnf + 1}\n"
1315 f"set interface state ipip{i} up\n"
1316 f"ip route add {ip_address(raddr_ip1) + tnl}/32 via ipip{i}\n\n"
1319 IPsecUtil._close_and_copy_ipsec_script_files(
1320 u"DUT1", nodes, n_instances, dut1_scripts)
1321 IPsecUtil._close_and_copy_ipsec_script_files(
1322 u"DUT2", nodes, n_instances, dut2_scripts)
1325 def vpp_ipsec_add_multiple_tunnels(
1326 nodes, interface1, interface2, n_tunnels, crypto_alg, integ_alg,
1327 tunnel_ip1, tunnel_ip2, raddr_ip1, raddr_ip2, raddr_range):
1328 """Create multiple IPsec tunnels between two VPP nodes.
1330 :param nodes: VPP nodes to create tunnels.
1331 :param interface1: Interface name or sw_if_index on node 1.
1332 :param interface2: Interface name or sw_if_index on node 2.
1333 :param n_tunnels: Number of tunnels to create.
1334 :param crypto_alg: The encryption algorithm name.
1335 :param integ_alg: The integrity algorithm name.
1336 :param tunnel_ip1: Tunnel node1 IPv4 address.
1337 :param tunnel_ip2: Tunnel node2 IPv4 address.
1338 :param raddr_ip1: Policy selector remote IPv4 start address for the
1339 first tunnel in direction node1->node2.
1340 :param raddr_ip2: Policy selector remote IPv4 start address for the
1341 first tunnel in direction node2->node1.
1342 :param raddr_range: Mask specifying range of Policy selector Remote
1343 IPv4 addresses. Valid values are from 1 to 32.
1345 :type interface1: str or int
1346 :type interface2: str or int
1347 :type n_tunnels: int
1348 :type crypto_alg: CryptoAlg
1349 :type integ_alg: IntegAlg
1350 :type tunnel_ip1: str
1351 :type tunnel_ip2: str
1352 :type raddr_ip1: string
1353 :type raddr_ip2: string
1354 :type raddr_range: int
1364 crypto_key = gen_key(
1365 IPsecUtil.get_crypto_alg_key_len(crypto_alg)
1367 integ_key = gen_key(
1368 IPsecUtil.get_integ_alg_key_len(integ_alg)
1369 ).decode() if integ_alg else u""
1371 IPsecUtil.vpp_ipsec_set_ip_route(
1372 nodes[u"DUT1"], n_tunnels, tunnel_ip1, raddr_ip2, tunnel_ip2,
1373 interface1, raddr_range)
1374 IPsecUtil.vpp_ipsec_set_ip_route(
1375 nodes[u"DUT2"], n_tunnels, tunnel_ip2, raddr_ip1, tunnel_ip1,
1376 interface2, raddr_range)
1378 IPsecUtil.vpp_ipsec_add_spd(nodes[u"DUT1"], spd_id)
1379 IPsecUtil.vpp_ipsec_spd_add_if(nodes[u"DUT1"], spd_id, interface1)
1380 IPsecUtil.vpp_ipsec_policy_add(
1381 nodes[u"DUT1"], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
1382 proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
1384 IPsecUtil.vpp_ipsec_policy_add(
1385 nodes[u"DUT1"], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
1386 proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
1389 IPsecUtil.vpp_ipsec_add_spd(nodes[u"DUT2"], spd_id)
1390 IPsecUtil.vpp_ipsec_spd_add_if(nodes[u"DUT2"], spd_id, interface2)
1391 IPsecUtil.vpp_ipsec_policy_add(
1392 nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
1393 proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
1395 IPsecUtil.vpp_ipsec_policy_add(
1396 nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
1397 proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
1400 IPsecUtil.vpp_ipsec_add_sad_entries(
1401 nodes[u"DUT1"], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
1402 integ_alg, integ_key, tunnel_ip1, tunnel_ip2
1404 IPsecUtil.vpp_ipsec_spd_add_entries(
1405 nodes[u"DUT1"], n_tunnels, spd_id, p_lo, False, sa_id_1, raddr_ip2
1408 IPsecUtil.vpp_ipsec_add_sad_entries(
1409 nodes[u"DUT2"], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
1410 integ_alg, integ_key, tunnel_ip1, tunnel_ip2
1412 IPsecUtil.vpp_ipsec_spd_add_entries(
1413 nodes[u"DUT2"], n_tunnels, spd_id, p_lo, True, sa_id_1, raddr_ip2
1416 IPsecUtil.vpp_ipsec_add_sad_entries(
1417 nodes[u"DUT2"], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
1418 integ_alg, integ_key, tunnel_ip2, tunnel_ip1
1421 IPsecUtil.vpp_ipsec_spd_add_entries(
1422 nodes[u"DUT2"], n_tunnels, spd_id, p_lo, False, sa_id_2, raddr_ip1
1425 IPsecUtil.vpp_ipsec_add_sad_entries(
1426 nodes[u"DUT1"], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
1427 integ_alg, integ_key, tunnel_ip2, tunnel_ip1
1430 IPsecUtil.vpp_ipsec_spd_add_entries(
1431 nodes[u"DUT1"], n_tunnels, spd_id, p_lo, True, sa_id_2, raddr_ip1
1435 def vpp_ipsec_show(node):
1436 """Run "show ipsec" debug CLI command.
1438 :param node: Node to run command on.
1441 PapiSocketExecutor.run_cli_cmd(node, u"show ipsec")