1 # Copyright (c) 2019 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."""
17 from random import choice
18 from string import letters
19 from ipaddress import ip_network, ip_address
21 from enum import Enum, IntEnum
23 from resources.libraries.python.PapiExecutor import PapiExecutor
24 from resources.libraries.python.topology import Topology
25 from resources.libraries.python.VatExecutor import VatExecutor
26 from resources.libraries.python.VatJsonUtil import VatJsonUtil
30 """Generate random string as a key.
32 :param length: Length of generated payload.
34 :returns: The generated payload.
37 return ''.join(choice(letters) for _ in range(length)).encode('hex')
39 class PolicyAction(Enum):
45 def __init__(self, string):
49 class CryptoAlg(Enum):
50 """Encryption algorithms."""
51 AES_CBC_128 = ('aes-cbc-128', 'AES-CBC', 16)
52 AES_CBC_256 = ('aes-cbc-256', 'AES-CBC', 32)
53 AES_GCM_128 = ('aes-gcm-128', 'AES-GCM', 16)
54 AES_GCM_256 = ('aes-gcm-256', 'AES-GCM', 32)
56 def __init__(self, alg_name, scapy_name, key_len):
57 self.alg_name = alg_name
58 self.scapy_name = scapy_name
59 self.key_len = key_len
63 """Integrity algorithm."""
64 SHA_256_128 = ('sha-256-128', 'SHA2-256-128', 32)
65 SHA_512_256 = ('sha-512-256', 'SHA2-512-256', 64)
66 AES_GCM_128 = ('aes-gcm-128', 'AES-GCM', 16)
67 AES_GCM_256 = ('aes-gcm-256', 'AES-GCM', 32)
69 def __init__(self, alg_name, scapy_name, key_len):
70 self.alg_name = alg_name
71 self.scapy_name = scapy_name
72 self.key_len = key_len
75 class IPsecProto(IntEnum):
81 class IPsecUtil(object):
82 """IPsec utilities."""
85 def policy_action_bypass():
86 """Return policy action bypass.
88 :returns: PolicyAction enum BYPASS object.
91 return PolicyAction.BYPASS
94 def policy_action_discard():
95 """Return policy action discard.
97 :returns: PolicyAction enum DISCARD object.
100 return PolicyAction.DISCARD
103 def policy_action_protect():
104 """Return policy action protect.
106 :returns: PolicyAction enum PROTECT object.
109 return PolicyAction.PROTECT
112 def crypto_alg_aes_cbc_128():
113 """Return encryption algorithm aes-cbc-128.
115 :returns: CryptoAlg enum AES_CBC_128 object.
118 return CryptoAlg.AES_CBC_128
121 def crypto_alg_aes_cbc_192():
122 """Return encryption algorithm aes-cbc-192.
124 :returns: CryptoAlg enum AES_CBC_192 objec.
127 return CryptoAlg.AES_CBC_192
130 def crypto_alg_aes_cbc_256():
131 """Return encryption algorithm aes-cbc-256.
133 :returns: CryptoAlg enum AES_CBC_256 object.
136 return CryptoAlg.AES_CBC_256
139 def crypto_alg_aes_gcm_128():
140 """Return encryption algorithm aes-gcm-128.
142 :returns: CryptoAlg enum AES_GCM_128 object.
145 return CryptoAlg.AES_GCM_128
148 def crypto_alg_aes_gcm_256():
149 """Return encryption algorithm aes-gcm-256.
151 :returns: CryptoAlg enum AES_GCM_128 object.
154 return CryptoAlg.AES_GCM_256
157 def get_crypto_alg_key_len(crypto_alg):
158 """Return encryption algorithm key length.
160 :param crypto_alg: Encryption algorithm.
161 :type crypto_alg: CryptoAlg
162 :returns: Key length.
165 return crypto_alg.key_len
168 def get_crypto_alg_scapy_name(crypto_alg):
169 """Return encryption algorithm scapy name.
171 :param crypto_alg: Encryption algorithm.
172 :type crypto_alg: CryptoAlg
173 :returns: Algorithm scapy name.
176 return crypto_alg.scapy_name
179 def integ_alg_sha1_96():
180 """Return integrity algorithm SHA1-96.
182 :returns: IntegAlg enum SHA1_96 object.
185 return IntegAlg.SHA1_96
188 def integ_alg_sha_256_128():
189 """Return integrity algorithm SHA-256-128.
191 :returns: IntegAlg enum SHA_256_128 object.
194 return IntegAlg.SHA_256_128
197 def integ_alg_sha_384_192():
198 """Return integrity algorithm SHA-384-192.
200 :returns: IntegAlg enum SHA_384_192 object.
203 return IntegAlg.SHA_384_192
206 def integ_alg_sha_512_256():
207 """Return integrity algorithm SHA-512-256.
209 :returns: IntegAlg enum SHA_512_256 object.
212 return IntegAlg.SHA_512_256
215 def integ_alg_aes_gcm_128():
216 """Return integrity algorithm AES-GCM-128.
218 :returns: IntegAlg enum AES_GCM_128 object.
221 return IntegAlg.AES_GCM_128
224 def integ_alg_aes_gcm_256():
225 """Return integrity algorithm AES-GCM-256.
227 :returns: IntegAlg enum AES_GCM_256 object.
230 return IntegAlg.AES_GCM_256
233 def get_integ_alg_key_len(integ_alg):
234 """Return integrity algorithm key length.
236 :param integ_alg: Integrity algorithm.
237 :type integ_alg: IntegAlg
238 :returns: Key length.
241 return integ_alg.key_len
244 def get_integ_alg_scapy_name(integ_alg):
245 """Return integrity algorithm scapy name.
247 :param integ_alg: Integrity algorithm.
248 :type integ_alg: IntegAlg
249 :returns: Algorithm scapy name.
252 return integ_alg.scapy_name
255 def ipsec_proto_esp():
256 """Return IPSec protocol ESP.
258 :returns: IPsecProto enum ESP object.
261 return int(IPsecProto.ESP)
264 def ipsec_proto_ah():
265 """Return IPSec protocol AH.
267 :returns: IPsecProto enum AH object.
270 return int(IPsecProto.SEC_AH)
273 def vpp_ipsec_select_backend(node, protocol, index=1):
274 """Select IPsec backend.
276 :param node: VPP node to select IPsec backend on.
277 :param protocol: IPsec protocol.
278 :param index: Backend index.
280 :type protocol: IPsecProto
282 :raises RuntimeError: If failed to select IPsec backend or if no API
286 cmd = 'ipsec_select_backend'
287 cmd_reply = 'ipsec_select_backend_reply'
288 err_msg = 'Failed to select IPsec backend on host {host}'.format(
290 args = dict(protocol=protocol, index=index)
291 with PapiExecutor(node) as papi_exec:
292 papi_resp = papi_exec.add(cmd, **args).execute_should_pass(err_msg)
293 data = papi_resp.reply[0]['api_reply'][cmd_reply]
294 if data['retval'] != 0:
295 raise RuntimeError('Failed to select IPsec backend on host {host}'.
296 format(host=node['host']))
299 def vpp_ipsec_backend_dump(node):
300 """Dump IPsec backends.
302 :param node: VPP node to dump IPsec backend on.
306 err_msg = 'Failed to dump IPsec backends on host {host}'.format(
308 with PapiExecutor(node) as papi_exec:
309 papi_exec.add('ipsec_backend_dump').execute_should_pass(
310 err_msg, process_reply=False)
313 def vpp_ipsec_add_sad_entry(node, sad_id, spi, crypto_alg, crypto_key,
314 integ_alg, integ_key, tunnel_src=None,
316 """Create Security Association Database entry on the VPP node.
318 :param node: VPP node to add SAD entry on.
319 :param sad_id: SAD entry ID.
320 :param spi: Security Parameter Index of this SAD entry.
321 :param crypto_alg: The encryption algorithm name.
322 :param crypto_key: The encryption key string.
323 :param integ_alg: The integrity algorithm name.
324 :param integ_key: The integrity key string.
325 :param tunnel_src: Tunnel header source IPv4 or IPv6 address. If not
326 specified ESP transport mode is used.
327 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address. If
328 not specified ESP transport mode is used.
332 :type crypto_alg: CryptoAlg
333 :type crypto_key: str
334 :type integ_alg: IntegAlg
336 :type tunnel_src: str
337 :type tunnel_dst: str
339 ckey = crypto_key.encode('hex')
340 ikey = integ_key.encode('hex')
341 tunnel = 'tunnel-src {0} tunnel-dst {1}'.format(tunnel_src, tunnel_dst)\
342 if tunnel_src is not None and tunnel_dst is not None else ''
344 out = VatExecutor.cmd_from_template(node,
345 'ipsec/ipsec_sad_add_entry.vat',
346 sad_id=sad_id, spi=spi,
347 calg=crypto_alg.alg_name, ckey=ckey,
348 ialg=integ_alg.alg_name, ikey=ikey,
350 VatJsonUtil.verify_vat_retval(
352 err_msg='Add SAD entry failed on {0}'.format(node['host']))
355 def vpp_ipsec_add_sad_entries(node, n_entries, sad_id, spi, crypto_alg,
356 crypto_key, integ_alg, integ_key,
357 tunnel_src=None, tunnel_dst=None):
358 """Create multiple Security Association Database entries on VPP node.
360 :param node: VPP node to add SAD entry on.
361 :param n_entries: Number of SAD entries to be created.
362 :param sad_id: First SAD entry ID. All subsequent SAD entries will have
364 :param spi: Security Parameter Index of first SAD entry. All subsequent
365 SAD entries will have spi incremented by 1.
366 :param crypto_alg: The encryption algorithm name.
367 :param crypto_key: The encryption key string.
368 :param integ_alg: The integrity algorithm name.
369 :param integ_key: The integrity key string.
370 :param tunnel_src: Tunnel header source IPv4 or IPv6 address. If not
371 specified ESP transport mode is used.
372 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address. If
373 not specified ESP transport mode is used.
378 :type crypto_alg: CryptoAlg
379 :type crypto_key: str
380 :type integ_alg: IntegAlg
382 :type tunnel_src: str
383 :type tunnel_dst: str
385 tmp_filename = '/tmp/ipsec_sad_{0}_add_del_entry.script'.format(sad_id)
387 addr_incr = 1 << (32 - 24)
389 with open(tmp_filename, 'w') as tmp_file:
390 for i in range(0, n_entries):
392 if not crypto_alg.alg_name.startswith('aes-gcm-'):
394 'integ-alg {integ_alg} integ-key {integ_key}'.
396 integ_alg=integ_alg.alg_name,
397 integ_key=integ_key))
399 'tunnel-src {laddr} tunnel-dst {raddr}'.
401 laddr=ip_address(unicode(tunnel_src)) + i * addr_incr,
402 raddr=ip_address(unicode(tunnel_dst)) + i * addr_incr)
403 if tunnel_src and tunnel_dst is not None else '')
405 'exec ipsec sa add {sad_id} esp spi {spi} '
406 'crypto-alg {crypto_alg} crypto-key {crypto_key} '
407 '{integ} {tunnel}\n'.
411 crypto_alg=crypto_alg.alg_name,
412 crypto_key=crypto_key,
417 vat.execute_script(tmp_filename, node, timeout=300, json_out=False,
418 copy_on_execute=True)
419 os.remove(tmp_filename)
422 def vpp_ipsec_set_ip_route(node, n_tunnels, tunnel_src, traffic_addr,
423 tunnel_dst, interface, raddr_range):
424 """Set IP address and route on interface.
426 :param node: VPP node to add config on.
427 :param n_tunnels: Number of tunnels to create.
428 :param tunnel_src: Tunnel header source IPv4 or IPv6 address.
429 :param traffic_addr: Traffic destination IP address to route.
430 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address.
431 :param interface: Interface key on node 1.
432 :param raddr_range: Mask specifying range of Policy selector Remote IPv4
433 addresses. Valid values are from 1 to 32.
436 :type tunnel_src: str
437 :type traffic_addr: str
438 :type tunnel_dst: str
440 :type raddr_range: int
442 tmp_filename = '/tmp/ipsec_set_ip.script'
444 addr_incr = 1 << (32 - raddr_range)
446 with open(tmp_filename, 'w') as tmp_file:
447 for i in range(0, n_tunnels):
449 'exec set interface ip address {interface} {laddr}/24\n'
450 'exec ip route add {taddr}/32 via {raddr} {interface}\n'.
452 interface=Topology.get_interface_name(node, interface),
453 laddr=ip_address(unicode(tunnel_src)) + i * addr_incr,
454 raddr=ip_address(unicode(tunnel_dst)) + i * addr_incr,
455 taddr=ip_address(unicode(traffic_addr)) + i))
458 vat.execute_script(tmp_filename, node, timeout=300, json_out=False,
459 copy_on_execute=True)
460 os.remove(tmp_filename)
463 def vpp_ipsec_sa_set_key(node, sa_id, crypto_key, integ_key):
464 """Update Security Association (SA) keys.
466 :param node: VPP node to update SA keys.
467 :param sa_id: SAD entry ID.
468 :param crypto_key: The encryption key string.
469 :param integ_key: The integrity key string.
472 :type crypto_key: str
475 ckey = crypto_key.encode('hex')
476 ikey = integ_key.encode('hex')
478 out = VatExecutor.cmd_from_template(
479 node, 'ipsec/ipsec_sa_set_key.vat', json_param=False, sa_id=sa_id,
480 ckey=ckey, ikey=ikey)
481 VatJsonUtil.verify_vat_retval(
483 err_msg='Update SA key failed on {0}'.format(node['host']))
486 def vpp_ipsec_add_spd(node, spd_id):
487 """Create Security Policy Database on the VPP node.
489 :param node: VPP node to add SPD on.
490 :param spd_id: SPD ID.
494 out = VatExecutor.cmd_from_template(node, 'ipsec/ipsec_spd_add.vat',
496 VatJsonUtil.verify_vat_retval(
498 err_msg='Add SPD {0} failed on {1}'.format(spd_id, node['host']))
501 def vpp_ipsec_spd_add_if(node, spd_id, interface):
502 """Add interface to the Security Policy Database.
504 :param node: VPP node.
505 :param spd_id: SPD ID to add interface on.
506 :param interface: Interface name or sw_if_index.
509 :type interface: str or int
511 sw_if_index = Topology.get_interface_sw_index(node, interface)\
512 if isinstance(interface, basestring) else interface
514 out = VatExecutor.cmd_from_template(node,
515 'ipsec/ipsec_interface_add_spd.vat',
516 spd_id=spd_id, sw_if_id=sw_if_index)
517 VatJsonUtil.verify_vat_retval(
519 err_msg='Add interface {0} to SPD {1} failed on {2}'.format(
520 interface, spd_id, node['host']))
523 def vpp_ipsec_policy_add(node, spd_id, priority, action, inbound=True,
524 sa_id=None, laddr_range=None, raddr_range=None,
525 proto=None, lport_range=None, rport_range=None,
527 """Create Security Policy Database entry on the VPP node.
529 :param node: VPP node to add SPD entry on.
530 :param spd_id: SPD ID to add entry on.
531 :param priority: SPD entry priority, higher number = higher priority.
532 :param action: Policy action.
533 :param inbound: If True policy is for inbound traffic, otherwise
535 :param sa_id: SAD entry ID for protect action.
536 :param laddr_range: Policy selector local IPv4 or IPv6 address range in
537 format IP/prefix or IP/mask. If no mask is provided,
538 it's considered to be /32.
539 :param raddr_range: Policy selector remote IPv4 or IPv6 address range in
540 format IP/prefix or IP/mask. If no mask is provided,
541 it's considered to be /32.
542 :param proto: Policy selector next layer protocol number.
543 :param lport_range: Policy selector local TCP/UDP port range in format
544 <port_start>-<port_end>.
545 :param rport_range: Policy selector remote TCP/UDP port range in format
546 <port_start>-<port_end>.
547 :param is_ipv6: True in case of IPv6 policy when IPv6 address range is
548 not defined so it will default to address ::/0, otherwise False.
552 :type action: PolicyAction
555 :type laddr_range: string
556 :type raddr_range: string
558 :type lport_range: string
559 :type rport_range: string
562 direction = 'inbound' if inbound else 'outbound'
564 if laddr_range is None and is_ipv6:
567 if raddr_range is None and is_ipv6:
570 act_str = action.value
571 if PolicyAction.PROTECT == action and sa_id is not None:
572 act_str += ' sa {0}'.format(sa_id)
575 if laddr_range is not None:
576 net = ip_network(unicode(laddr_range), strict=False)
577 selector += 'local-ip-range {0} - {1} '.format(
578 net.network_address, net.broadcast_address)
579 if raddr_range is not None:
580 net = ip_network(unicode(raddr_range), strict=False)
581 selector += 'remote-ip-range {0} - {1} '.format(
582 net.network_address, net.broadcast_address)
583 if proto is not None:
584 selector += 'protocol {0} '.format(proto)
585 if lport_range is not None:
586 selector += 'local-port-range {0} '.format(lport_range)
587 if rport_range is not None:
588 selector += 'remote-port-range {0} '.format(rport_range)
590 out = VatExecutor.cmd_from_template(
591 node, 'ipsec/ipsec_policy_add.vat', json_param=False, spd_id=spd_id,
592 priority=priority, action=act_str, direction=direction,
594 VatJsonUtil.verify_vat_retval(
596 err_msg='Add IPsec policy ID {0} failed on {1}'.format(
597 spd_id, node['host']))
600 def vpp_ipsec_spd_add_entries(node, n_entries, spd_id, priority, inbound,
602 """Create multiple Security Policy Database entries on the VPP node.
604 :param node: VPP node to add SPD entries on.
605 :param n_entries: Number of SPD entries to be added.
606 :param spd_id: SPD ID to add entries on.
607 :param priority: SPD entries priority, higher number = higher priority.
608 :param inbound: If True policy is for inbound traffic, otherwise
610 :param sa_id: SAD entry ID for first entry. Each subsequent entry will
611 SAD entry ID incremented by 1.
612 :param raddr_ip: Policy selector remote IPv4 start address for the first
613 entry. Remote IPv4 end address will be calculated depending on
614 raddr_range parameter. Each subsequent entry will have start address
615 next after IPv4 end address of previous entry.
622 :type raddr_ip: string
624 tmp_filename = '/tmp/ipsec_spd_{0}_add_del_entry.script'.format(sa_id)
626 with open(tmp_filename, 'w') as tmp_file:
627 for i in range(0, n_entries):
628 raddr_s = ip_address(unicode(raddr_ip)) + i
629 raddr_e = ip_address(unicode(raddr_ip)) + (i + 1) - 1
631 'exec ipsec policy add spd {spd_id} priority {priority} '
632 '{direction} action protect sa {sa_id} '
633 'remote-ip-range {raddr_s} - {raddr_e}\n'.
637 direction='inbound' if inbound else 'outbound',
641 tmp_file.write(tunnel)
643 vat.execute_script(tmp_filename, node, timeout=300, json_out=False,
644 copy_on_execute=True)
645 os.remove(tmp_filename)
648 def vpp_ipsec_create_tunnel_interfaces(nodes, if1_ip_addr, if2_ip_addr,
649 if1_key, if2_key, n_tunnels,
650 crypto_alg, integ_alg, raddr_ip1,
651 raddr_ip2, raddr_range):
652 """Create multiple IPsec tunnel interfaces between two VPP nodes.
654 :param nodes: VPP nodes to create tunnel interfaces.
655 :param if1_ip_addr: VPP node 1 interface IP4 address.
656 :param if2_ip_addr: VPP node 2 interface IP4 address.
657 :param if1_key: VPP node 1 interface key from topology file.
658 :param if2_key: VPP node 2 interface key from topology file.
659 :param n_tunnels: Number of tunnell interfaces to create.
660 :param crypto_alg: The encryption algorithm name.
661 :param integ_alg: The integrity algorithm name.
662 :param raddr_ip1: Policy selector remote IPv4 start address for the
663 first tunnel in direction node1->node2.
664 :param raddr_ip2: Policy selector remote IPv4 start address for the
665 first tunnel in direction node2->node1.
666 :param raddr_range: Mask specifying range of Policy selector Remote IPv4
667 addresses. Valid values are from 1 to 32.
669 :type if1_ip_addr: str
670 :type if2_ip_addr: str
674 :type crypto_alg: CryptoAlg
675 :type integ_alg: IntegAlg
676 :type raddr_ip1: string
677 :type raddr_ip2: string
678 :type raddr_range: int
682 addr_incr = 1 << (32 - raddr_range)
684 tmp_fn1 = '/tmp/ipsec_create_tunnel_dut1.config'
685 tmp_fn2 = '/tmp/ipsec_create_tunnel_dut2.config'
689 with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2:
690 for i in range(0, n_tunnels):
691 ckey = gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
692 ikey = gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
694 if not crypto_alg.alg_name.startswith('aes-gcm-'):
696 'integ_alg {integ_alg} '
697 'local_integ_key {local_integ_key} '
698 'remote_integ_key {remote_integ_key} '
700 integ_alg=integ_alg.alg_name,
701 local_integ_key=ikey,
702 remote_integ_key=ikey))
704 'exec set interface ip address {uifc} {laddr}/24\n'
705 'ipsec_tunnel_if_add_del '
706 'local_spi {local_spi} '
707 'remote_spi {remote_spi} '
708 'crypto_alg {crypto_alg} '
709 'local_crypto_key {local_crypto_key} '
710 'remote_crypto_key {remote_crypto_key} '
713 'remote_ip {raddr}\n'
716 remote_spi=spi_2 + i,
717 crypto_alg=crypto_alg.alg_name,
718 local_crypto_key=ckey,
719 remote_crypto_key=ckey,
721 laddr=ip_address(unicode(if1_ip_addr)) + i * addr_incr,
722 raddr=ip_address(unicode(if2_ip_addr)) + i * addr_incr,
723 uifc=Topology.get_interface_name(nodes['DUT1'],
726 'exec set interface ip address {uifc} {laddr}/24\n'
727 'ipsec_tunnel_if_add_del '
728 'local_spi {local_spi} '
729 'remote_spi {remote_spi} '
730 'crypto_alg {crypto_alg} '
731 'local_crypto_key {local_crypto_key} '
732 'remote_crypto_key {remote_crypto_key} '
735 'remote_ip {raddr}\n'
738 remote_spi=spi_1 + i,
739 crypto_alg=crypto_alg.alg_name,
740 local_crypto_key=ckey,
741 remote_crypto_key=ckey,
743 laddr=ip_address(unicode(if2_ip_addr)) + i * addr_incr,
744 raddr=ip_address(unicode(if1_ip_addr)) + i * addr_incr,
745 uifc=Topology.get_interface_name(nodes['DUT2'],
747 vat.execute_script(tmp_fn1, nodes['DUT1'], timeout=300, json_out=False,
748 copy_on_execute=True)
749 vat.execute_script(tmp_fn2, nodes['DUT2'], timeout=300, json_out=False,
750 copy_on_execute=True)
754 with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2:
755 for i in range(0, n_tunnels):
757 'exec set interface unnumbered ipsec{i} use {uifc}\n'
758 'exec set interface state ipsec{i} up\n'
759 'exec ip route add {taddr}/32 via {raddr} ipsec{i}\n'
761 taddr=ip_address(unicode(raddr_ip2)) + i,
762 raddr=ip_address(unicode(if2_ip_addr)) + i * addr_incr,
764 uifc=Topology.get_interface_name(nodes['DUT1'],
767 'exec set interface unnumbered ipsec{i} use {uifc}\n'
768 'exec set interface state ipsec{i} up\n'
769 'exec ip route add {taddr}/32 via {raddr} ipsec{i}\n'
771 taddr=ip_address(unicode(raddr_ip1)) + i,
772 raddr=ip_address(unicode(if1_ip_addr)) + i * addr_incr,
774 uifc=Topology.get_interface_name(nodes['DUT2'],
776 vat.execute_script(tmp_fn1, nodes['DUT1'], timeout=300, json_out=False,
777 copy_on_execute=True)
778 vat.execute_script(tmp_fn2, nodes['DUT2'], timeout=300, json_out=False,
779 copy_on_execute=True)
784 def vpp_ipsec_add_multiple_tunnels(nodes, interface1, interface2,
785 n_tunnels, crypto_alg, integ_alg,
786 tunnel_ip1, tunnel_ip2, raddr_ip1,
787 raddr_ip2, raddr_range):
788 """Create multiple IPsec tunnels between two VPP nodes.
790 :param nodes: VPP nodes to create tunnels.
791 :param interface1: Interface name or sw_if_index on node 1.
792 :param interface2: Interface name or sw_if_index on node 2.
793 :param n_tunnels: Number of tunnels to create.
794 :param crypto_alg: The encryption algorithm name.
795 :param integ_alg: The integrity algorithm name.
796 :param tunnel_ip1: Tunnel node1 IPv4 address.
797 :param tunnel_ip2: Tunnel node2 IPv4 address.
798 :param raddr_ip1: Policy selector remote IPv4 start address for the
799 first tunnel in direction node1->node2.
800 :param raddr_ip2: Policy selector remote IPv4 start address for the
801 first tunnel in direction node2->node1.
802 :param raddr_range: Mask specifying range of Policy selector Remote IPv4
803 addresses. Valid values are from 1 to 32.
805 :type interface1: str or int
806 :type interface2: str or int
808 :type crypto_alg: CryptoAlg
810 :type tunnel_ip1: str
811 :type tunnel_ip2: str
812 :type raddr_ip1: string
813 :type raddr_ip2: string
814 :type raddr_range: int
824 crypto_key = gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
825 integ_key = gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
827 IPsecUtil.vpp_ipsec_set_ip_route(
828 nodes['DUT1'], n_tunnels, tunnel_ip1, raddr_ip2, tunnel_ip2,
829 interface1, raddr_range)
830 IPsecUtil.vpp_ipsec_set_ip_route(
831 nodes['DUT2'], n_tunnels, tunnel_ip2, raddr_ip1, tunnel_ip1,
832 interface2, raddr_range)
834 IPsecUtil.vpp_ipsec_add_spd(
835 nodes['DUT1'], spd_id)
836 IPsecUtil.vpp_ipsec_spd_add_if(
837 nodes['DUT1'], spd_id, interface1)
838 IPsecUtil.vpp_ipsec_policy_add(
839 nodes['DUT1'], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
841 IPsecUtil.vpp_ipsec_policy_add(
842 nodes['DUT1'], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
845 IPsecUtil.vpp_ipsec_add_spd(
846 nodes['DUT2'], spd_id)
847 IPsecUtil.vpp_ipsec_spd_add_if(
848 nodes['DUT2'], spd_id, interface2)
849 IPsecUtil.vpp_ipsec_policy_add(
850 nodes['DUT2'], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
852 IPsecUtil.vpp_ipsec_policy_add(
853 nodes['DUT2'], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
856 IPsecUtil.vpp_ipsec_add_sad_entries(
857 nodes['DUT1'], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
858 integ_alg, integ_key, tunnel_ip1, tunnel_ip2)
860 IPsecUtil.vpp_ipsec_spd_add_entries(
861 nodes['DUT1'], n_tunnels, spd_id, p_lo, False, sa_id_1, raddr_ip2)
863 IPsecUtil.vpp_ipsec_add_sad_entries(
864 nodes['DUT2'], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
865 integ_alg, integ_key, tunnel_ip1, tunnel_ip2)
867 IPsecUtil.vpp_ipsec_spd_add_entries(
868 nodes['DUT2'], n_tunnels, spd_id, p_lo, True, sa_id_1, raddr_ip2)
870 IPsecUtil.vpp_ipsec_add_sad_entries(
871 nodes['DUT2'], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
872 integ_alg, integ_key, tunnel_ip2, tunnel_ip1)
874 IPsecUtil.vpp_ipsec_spd_add_entries(
875 nodes['DUT2'], n_tunnels, spd_id, p_lo, False, sa_id_2, raddr_ip1)
877 IPsecUtil.vpp_ipsec_add_sad_entries(
878 nodes['DUT1'], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
879 integ_alg, integ_key, tunnel_ip2, tunnel_ip1)
881 IPsecUtil.vpp_ipsec_spd_add_entries(
882 nodes['DUT1'], n_tunnels, spd_id, p_lo, True, sa_id_2, raddr_ip1)
885 def vpp_ipsec_show(node):
886 """Run "show ipsec" debug CLI command.
888 :param node: Node to run command on.
891 VatExecutor().execute_script('ipsec/ipsec_show.vat', node,