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_256():
122 """Return encryption algorithm aes-cbc-256.
124 :returns: CryptoAlg enum AES_CBC_256 object.
127 return CryptoAlg.AES_CBC_256
130 def crypto_alg_aes_gcm_128():
131 """Return encryption algorithm aes-gcm-128.
133 :returns: CryptoAlg enum AES_GCM_128 object.
136 return CryptoAlg.AES_GCM_128
139 def crypto_alg_aes_gcm_256():
140 """Return encryption algorithm aes-gcm-256.
142 :returns: CryptoAlg enum AES_GCM_128 object.
145 return CryptoAlg.AES_GCM_256
148 def get_crypto_alg_key_len(crypto_alg):
149 """Return encryption algorithm key length.
151 :param crypto_alg: Encryption algorithm.
152 :type crypto_alg: CryptoAlg
153 :returns: Key length.
156 return crypto_alg.key_len
159 def get_crypto_alg_scapy_name(crypto_alg):
160 """Return encryption algorithm scapy name.
162 :param crypto_alg: Encryption algorithm.
163 :type crypto_alg: CryptoAlg
164 :returns: Algorithm scapy name.
167 return crypto_alg.scapy_name
170 def integ_alg_sha_256_128():
171 """Return integrity algorithm SHA-256-128.
173 :returns: IntegAlg enum SHA_256_128 object.
176 return IntegAlg.SHA_256_128
179 def integ_alg_sha_512_256():
180 """Return integrity algorithm SHA-512-256.
182 :returns: IntegAlg enum SHA_512_256 object.
185 return IntegAlg.SHA_512_256
188 def integ_alg_aes_gcm_128():
189 """Return integrity algorithm AES-GCM-128.
191 :returns: IntegAlg enum AES_GCM_128 object.
194 return IntegAlg.AES_GCM_128
197 def integ_alg_aes_gcm_256():
198 """Return integrity algorithm AES-GCM-256.
200 :returns: IntegAlg enum AES_GCM_256 object.
203 return IntegAlg.AES_GCM_256
206 def get_integ_alg_key_len(integ_alg):
207 """Return integrity algorithm key length.
209 :param integ_alg: Integrity algorithm.
210 :type integ_alg: IntegAlg
211 :returns: Key length.
214 return integ_alg.key_len
217 def get_integ_alg_scapy_name(integ_alg):
218 """Return integrity algorithm scapy name.
220 :param integ_alg: Integrity algorithm.
221 :type integ_alg: IntegAlg
222 :returns: Algorithm scapy name.
225 return integ_alg.scapy_name
228 def ipsec_proto_esp():
229 """Return IPSec protocol ESP.
231 :returns: IPsecProto enum ESP object.
234 return int(IPsecProto.ESP)
237 def ipsec_proto_ah():
238 """Return IPSec protocol AH.
240 :returns: IPsecProto enum AH object.
243 return int(IPsecProto.SEC_AH)
246 def vpp_ipsec_select_backend(node, protocol, index=1):
247 """Select IPsec backend.
249 :param node: VPP node to select IPsec backend on.
250 :param protocol: IPsec protocol.
251 :param index: Backend index.
253 :type protocol: IPsecProto
255 :raises RuntimeError: If failed to select IPsec backend or if no API
259 cmd = 'ipsec_select_backend'
260 cmd_reply = 'ipsec_select_backend_reply'
261 err_msg = 'Failed to select IPsec backend on host {host}'.format(
263 args = dict(protocol=protocol, index=index)
264 with PapiExecutor(node) as papi_exec:
265 papi_resp = papi_exec.add(cmd, **args).execute_should_pass(err_msg)
266 data = papi_resp.reply[0]['api_reply'][cmd_reply]
267 if data['retval'] != 0:
268 raise RuntimeError('Failed to select IPsec backend on host {host}'.
269 format(host=node['host']))
272 def vpp_ipsec_backend_dump(node):
273 """Dump IPsec backends.
275 :param node: VPP node to dump IPsec backend on.
279 err_msg = 'Failed to dump IPsec backends on host {host}'.format(
281 with PapiExecutor(node) as papi_exec:
282 papi_exec.add('ipsec_backend_dump').execute_should_pass(
283 err_msg, process_reply=False)
286 def vpp_ipsec_add_sad_entry(node, sad_id, spi, crypto_alg, crypto_key,
287 integ_alg, integ_key, tunnel_src=None,
289 """Create Security Association Database entry on the VPP node.
291 :param node: VPP node to add SAD entry on.
292 :param sad_id: SAD entry ID.
293 :param spi: Security Parameter Index of this SAD entry.
294 :param crypto_alg: The encryption algorithm name.
295 :param crypto_key: The encryption key string.
296 :param integ_alg: The integrity algorithm name.
297 :param integ_key: The integrity key string.
298 :param tunnel_src: Tunnel header source IPv4 or IPv6 address. If not
299 specified ESP transport mode is used.
300 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address. If
301 not specified ESP transport mode is used.
305 :type crypto_alg: CryptoAlg
306 :type crypto_key: str
307 :type integ_alg: IntegAlg
309 :type tunnel_src: str
310 :type tunnel_dst: str
312 ckey = crypto_key.encode('hex')
313 ikey = integ_key.encode('hex')
314 tunnel = 'tunnel-src {0} tunnel-dst {1}'.format(tunnel_src, tunnel_dst)\
315 if tunnel_src is not None and tunnel_dst is not None else ''
317 out = VatExecutor.cmd_from_template(node,
318 'ipsec/ipsec_sad_add_entry.vat',
319 sad_id=sad_id, spi=spi,
320 calg=crypto_alg.alg_name, ckey=ckey,
321 ialg=integ_alg.alg_name, ikey=ikey,
323 VatJsonUtil.verify_vat_retval(
325 err_msg='Add SAD entry failed on {0}'.format(node['host']))
328 def vpp_ipsec_add_sad_entries(node, n_entries, sad_id, spi, crypto_alg,
329 crypto_key, integ_alg, integ_key,
330 tunnel_src=None, tunnel_dst=None):
331 """Create multiple Security Association Database entries on VPP node.
333 :param node: VPP node to add SAD entry on.
334 :param n_entries: Number of SAD entries to be created.
335 :param sad_id: First SAD entry ID. All subsequent SAD entries will have
337 :param spi: Security Parameter Index of first SAD entry. All subsequent
338 SAD entries will have spi incremented by 1.
339 :param crypto_alg: The encryption algorithm name.
340 :param crypto_key: The encryption key string.
341 :param integ_alg: The integrity algorithm name.
342 :param integ_key: The integrity key string.
343 :param tunnel_src: Tunnel header source IPv4 or IPv6 address. If not
344 specified ESP transport mode is used.
345 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address. If
346 not specified ESP transport mode is used.
351 :type crypto_alg: CryptoAlg
352 :type crypto_key: str
353 :type integ_alg: IntegAlg
355 :type tunnel_src: str
356 :type tunnel_dst: str
358 tmp_filename = '/tmp/ipsec_sad_{0}_add_del_entry.script'.format(sad_id)
360 addr_incr = 1 << (32 - 24)
362 with open(tmp_filename, 'w') as tmp_file:
363 for i in range(0, n_entries):
365 if not crypto_alg.alg_name.startswith('aes-gcm-'):
367 'integ-alg {integ_alg} integ-key {integ_key}'.
369 integ_alg=integ_alg.alg_name,
370 integ_key=integ_key))
372 'tunnel-src {laddr} tunnel-dst {raddr}'.
374 laddr=ip_address(unicode(tunnel_src)) + i * addr_incr,
375 raddr=ip_address(unicode(tunnel_dst)) + i * addr_incr)
376 if tunnel_src and tunnel_dst is not None else '')
378 'exec ipsec sa add {sad_id} esp spi {spi} '
379 'crypto-alg {crypto_alg} crypto-key {crypto_key} '
380 '{integ} {tunnel}\n'.
384 crypto_alg=crypto_alg.alg_name,
385 crypto_key=crypto_key,
390 vat.execute_script(tmp_filename, node, timeout=300, json_out=False,
391 copy_on_execute=True)
392 os.remove(tmp_filename)
395 def vpp_ipsec_set_ip_route(node, n_tunnels, tunnel_src, traffic_addr,
396 tunnel_dst, interface, raddr_range):
397 """Set IP address and route on interface.
399 :param node: VPP node to add config on.
400 :param n_tunnels: Number of tunnels to create.
401 :param tunnel_src: Tunnel header source IPv4 or IPv6 address.
402 :param traffic_addr: Traffic destination IP address to route.
403 :param tunnel_dst: Tunnel header destination IPv4 or IPv6 address.
404 :param interface: Interface key on node 1.
405 :param raddr_range: Mask specifying range of Policy selector Remote IPv4
406 addresses. Valid values are from 1 to 32.
409 :type tunnel_src: str
410 :type traffic_addr: str
411 :type tunnel_dst: str
413 :type raddr_range: int
415 tmp_filename = '/tmp/ipsec_set_ip.script'
417 addr_incr = 1 << (32 - raddr_range)
419 with open(tmp_filename, 'w') as tmp_file:
420 for i in range(0, n_tunnels):
422 'exec set interface ip address {interface} {laddr}/24\n'
423 'exec ip route add {taddr}/32 via {raddr} {interface}\n'.
425 interface=Topology.get_interface_name(node, interface),
426 laddr=ip_address(unicode(tunnel_src)) + i * addr_incr,
427 raddr=ip_address(unicode(tunnel_dst)) + i * addr_incr,
428 taddr=ip_address(unicode(traffic_addr)) + i))
431 vat.execute_script(tmp_filename, node, timeout=300, json_out=False,
432 copy_on_execute=True)
433 os.remove(tmp_filename)
436 def vpp_ipsec_sa_set_key(node, sa_id, crypto_key, integ_key):
437 """Update Security Association (SA) keys.
439 :param node: VPP node to update SA keys.
440 :param sa_id: SAD entry ID.
441 :param crypto_key: The encryption key string.
442 :param integ_key: The integrity key string.
445 :type crypto_key: str
448 ckey = crypto_key.encode('hex')
449 ikey = integ_key.encode('hex')
451 out = VatExecutor.cmd_from_template(
452 node, 'ipsec/ipsec_sa_set_key.vat', json_param=False, sa_id=sa_id,
453 ckey=ckey, ikey=ikey)
454 VatJsonUtil.verify_vat_retval(
456 err_msg='Update SA key failed on {0}'.format(node['host']))
459 def vpp_ipsec_add_spd(node, spd_id):
460 """Create Security Policy Database on the VPP node.
462 :param node: VPP node to add SPD on.
463 :param spd_id: SPD ID.
467 out = VatExecutor.cmd_from_template(node, 'ipsec/ipsec_spd_add.vat',
469 VatJsonUtil.verify_vat_retval(
471 err_msg='Add SPD {0} failed on {1}'.format(spd_id, node['host']))
474 def vpp_ipsec_spd_add_if(node, spd_id, interface):
475 """Add interface to the Security Policy Database.
477 :param node: VPP node.
478 :param spd_id: SPD ID to add interface on.
479 :param interface: Interface name or sw_if_index.
482 :type interface: str or int
484 sw_if_index = Topology.get_interface_sw_index(node, interface)\
485 if isinstance(interface, basestring) else interface
487 out = VatExecutor.cmd_from_template(node,
488 'ipsec/ipsec_interface_add_spd.vat',
489 spd_id=spd_id, sw_if_id=sw_if_index)
490 VatJsonUtil.verify_vat_retval(
492 err_msg='Add interface {0} to SPD {1} failed on {2}'.format(
493 interface, spd_id, node['host']))
496 def vpp_ipsec_policy_add(node, spd_id, priority, action, inbound=True,
497 sa_id=None, laddr_range=None, raddr_range=None,
498 proto=None, lport_range=None, rport_range=None,
500 """Create Security Policy Database entry on the VPP node.
502 :param node: VPP node to add SPD entry on.
503 :param spd_id: SPD ID to add entry on.
504 :param priority: SPD entry priority, higher number = higher priority.
505 :param action: Policy action.
506 :param inbound: If True policy is for inbound traffic, otherwise
508 :param sa_id: SAD entry ID for protect action.
509 :param laddr_range: Policy selector local IPv4 or IPv6 address range in
510 format IP/prefix or IP/mask. If no mask is provided,
511 it's considered to be /32.
512 :param raddr_range: Policy selector remote IPv4 or IPv6 address range in
513 format IP/prefix or IP/mask. If no mask is provided,
514 it's considered to be /32.
515 :param proto: Policy selector next layer protocol number.
516 :param lport_range: Policy selector local TCP/UDP port range in format
517 <port_start>-<port_end>.
518 :param rport_range: Policy selector remote TCP/UDP port range in format
519 <port_start>-<port_end>.
520 :param is_ipv6: True in case of IPv6 policy when IPv6 address range is
521 not defined so it will default to address ::/0, otherwise False.
525 :type action: PolicyAction
528 :type laddr_range: string
529 :type raddr_range: string
531 :type lport_range: string
532 :type rport_range: string
535 direction = 'inbound' if inbound else 'outbound'
537 if laddr_range is None and is_ipv6:
540 if raddr_range is None and is_ipv6:
543 act_str = action.value
544 if PolicyAction.PROTECT == action and sa_id is not None:
545 act_str += ' sa {0}'.format(sa_id)
548 if laddr_range is not None:
549 net = ip_network(unicode(laddr_range), strict=False)
550 selector += 'local-ip-range {0} - {1} '.format(
551 net.network_address, net.broadcast_address)
552 if raddr_range is not None:
553 net = ip_network(unicode(raddr_range), strict=False)
554 selector += 'remote-ip-range {0} - {1} '.format(
555 net.network_address, net.broadcast_address)
556 if proto is not None:
557 selector += 'protocol {0} '.format(proto)
558 if lport_range is not None:
559 selector += 'local-port-range {0} '.format(lport_range)
560 if rport_range is not None:
561 selector += 'remote-port-range {0} '.format(rport_range)
563 out = VatExecutor.cmd_from_template(
564 node, 'ipsec/ipsec_policy_add.vat', json_param=False, spd_id=spd_id,
565 priority=priority, action=act_str, direction=direction,
567 VatJsonUtil.verify_vat_retval(
569 err_msg='Add IPsec policy ID {0} failed on {1}'.format(
570 spd_id, node['host']))
573 def vpp_ipsec_spd_add_entries(node, n_entries, spd_id, priority, inbound,
575 """Create multiple Security Policy Database entries on the VPP node.
577 :param node: VPP node to add SPD entries on.
578 :param n_entries: Number of SPD entries to be added.
579 :param spd_id: SPD ID to add entries on.
580 :param priority: SPD entries priority, higher number = higher priority.
581 :param inbound: If True policy is for inbound traffic, otherwise
583 :param sa_id: SAD entry ID for first entry. Each subsequent entry will
584 SAD entry ID incremented by 1.
585 :param raddr_ip: Policy selector remote IPv4 start address for the first
586 entry. Remote IPv4 end address will be calculated depending on
587 raddr_range parameter. Each subsequent entry will have start address
588 next after IPv4 end address of previous entry.
595 :type raddr_ip: string
597 tmp_filename = '/tmp/ipsec_spd_{0}_add_del_entry.script'.format(sa_id)
599 with open(tmp_filename, 'w') as tmp_file:
600 for i in range(0, n_entries):
601 raddr_s = ip_address(unicode(raddr_ip)) + i
602 raddr_e = ip_address(unicode(raddr_ip)) + (i + 1) - 1
604 'exec ipsec policy add spd {spd_id} priority {priority} '
605 '{direction} action protect sa {sa_id} '
606 'remote-ip-range {raddr_s} - {raddr_e} '
607 'local-ip-range 0.0.0.0 - 255.255.255.255\n'.
611 direction='inbound' if inbound else 'outbound',
615 tmp_file.write(tunnel)
617 vat.execute_script(tmp_filename, node, timeout=300, json_out=False,
618 copy_on_execute=True)
619 os.remove(tmp_filename)
622 def vpp_ipsec_create_tunnel_interfaces(nodes, if1_ip_addr, if2_ip_addr,
623 if1_key, if2_key, n_tunnels,
624 crypto_alg, integ_alg, raddr_ip1,
625 raddr_ip2, raddr_range):
626 """Create multiple IPsec tunnel interfaces between two VPP nodes.
628 :param nodes: VPP nodes to create tunnel interfaces.
629 :param if1_ip_addr: VPP node 1 interface IP4 address.
630 :param if2_ip_addr: VPP node 2 interface IP4 address.
631 :param if1_key: VPP node 1 interface key from topology file.
632 :param if2_key: VPP node 2 interface key from topology file.
633 :param n_tunnels: Number of tunnell interfaces to create.
634 :param crypto_alg: The encryption algorithm name.
635 :param integ_alg: The integrity algorithm name.
636 :param raddr_ip1: Policy selector remote IPv4 start address for the
637 first tunnel in direction node1->node2.
638 :param raddr_ip2: Policy selector remote IPv4 start address for the
639 first tunnel in direction node2->node1.
640 :param raddr_range: Mask specifying range of Policy selector Remote IPv4
641 addresses. Valid values are from 1 to 32.
643 :type if1_ip_addr: str
644 :type if2_ip_addr: str
648 :type crypto_alg: CryptoAlg
649 :type integ_alg: IntegAlg
650 :type raddr_ip1: string
651 :type raddr_ip2: string
652 :type raddr_range: int
656 addr_incr = 1 << (32 - raddr_range)
658 tmp_fn1 = '/tmp/ipsec_create_tunnel_dut1.config'
659 tmp_fn2 = '/tmp/ipsec_create_tunnel_dut2.config'
663 with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2:
665 'exec create loopback interface\n'
666 'exec set interface state loop0 up\n'
667 'exec set interface ip address {uifc} {iaddr}/24\n'
669 iaddr=ip_address(unicode(if2_ip_addr)) - 1,
670 uifc=Topology.get_interface_name(nodes['DUT1'], if1_key)))
672 'exec set interface ip address {uifc} {iaddr}/24\n'
674 iaddr=ip_address(unicode(if2_ip_addr)),
675 uifc=Topology.get_interface_name(nodes['DUT2'], if2_key)))
676 for i in range(0, n_tunnels):
677 ckey = gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
678 ikey = gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
680 if not crypto_alg.alg_name.startswith('aes-gcm-'):
682 'integ_alg {integ_alg} '
683 'local_integ_key {local_integ_key} '
684 'remote_integ_key {remote_integ_key} '
686 integ_alg=integ_alg.alg_name,
687 local_integ_key=ikey,
688 remote_integ_key=ikey))
690 'exec set interface ip address loop0 {laddr}/32\n'
691 'ipsec_tunnel_if_add_del '
692 'local_spi {local_spi} '
693 'remote_spi {remote_spi} '
694 'crypto_alg {crypto_alg} '
695 'local_crypto_key {local_crypto_key} '
696 'remote_crypto_key {remote_crypto_key} '
699 'remote_ip {raddr}\n'
702 remote_spi=spi_2 + i,
703 crypto_alg=crypto_alg.alg_name,
704 local_crypto_key=ckey,
705 remote_crypto_key=ckey,
707 laddr=ip_address(unicode(if1_ip_addr)) + i * addr_incr,
708 raddr=ip_address(unicode(if2_ip_addr))))
710 'ipsec_tunnel_if_add_del '
711 'local_spi {local_spi} '
712 'remote_spi {remote_spi} '
713 'crypto_alg {crypto_alg} '
714 'local_crypto_key {local_crypto_key} '
715 'remote_crypto_key {remote_crypto_key} '
718 'remote_ip {raddr}\n'
721 remote_spi=spi_1 + i,
722 crypto_alg=crypto_alg.alg_name,
723 local_crypto_key=ckey,
724 remote_crypto_key=ckey,
726 laddr=ip_address(unicode(if2_ip_addr)),
727 raddr=ip_address(unicode(if1_ip_addr)) + i * addr_incr))
728 vat.execute_script(tmp_fn1, nodes['DUT1'], timeout=1800, json_out=False,
729 copy_on_execute=True)
730 vat.execute_script(tmp_fn2, nodes['DUT2'], timeout=1800, json_out=False,
731 copy_on_execute=True)
735 with open(tmp_fn1, 'w') as tmp_f1, open(tmp_fn2, 'w') as tmp_f2:
737 'exec ip route add {raddr} via {uifc} {iaddr}\n'
739 raddr=ip_network(unicode(if1_ip_addr+'/8'), False),
740 iaddr=ip_address(unicode(if2_ip_addr)) - 1,
741 uifc=Topology.get_interface_name(nodes['DUT2'], if2_key)))
742 for i in range(0, n_tunnels):
744 'exec set interface unnumbered ipsec{i} use {uifc}\n'
745 'exec set interface state ipsec{i} up\n'
746 'exec ip route add {taddr}/32 via ipsec{i}\n'
748 taddr=ip_address(unicode(raddr_ip2)) + i,
750 uifc=Topology.get_interface_name(nodes['DUT1'],
753 'exec set interface unnumbered ipsec{i} use {uifc}\n'
754 'exec set interface state ipsec{i} up\n'
755 'exec ip route add {taddr}/32 via ipsec{i}\n'
757 taddr=ip_address(unicode(raddr_ip1)) + i,
759 uifc=Topology.get_interface_name(nodes['DUT2'],
761 vat.execute_script(tmp_fn1, nodes['DUT1'], timeout=1800, json_out=False,
762 copy_on_execute=True)
763 vat.execute_script(tmp_fn2, nodes['DUT2'], timeout=1800, json_out=False,
764 copy_on_execute=True)
769 def vpp_ipsec_add_multiple_tunnels(nodes, interface1, interface2,
770 n_tunnels, crypto_alg, integ_alg,
771 tunnel_ip1, tunnel_ip2, raddr_ip1,
772 raddr_ip2, raddr_range):
773 """Create multiple IPsec tunnels between two VPP nodes.
775 :param nodes: VPP nodes to create tunnels.
776 :param interface1: Interface name or sw_if_index on node 1.
777 :param interface2: Interface name or sw_if_index on node 2.
778 :param n_tunnels: Number of tunnels to create.
779 :param crypto_alg: The encryption algorithm name.
780 :param integ_alg: The integrity algorithm name.
781 :param tunnel_ip1: Tunnel node1 IPv4 address.
782 :param tunnel_ip2: Tunnel node2 IPv4 address.
783 :param raddr_ip1: Policy selector remote IPv4 start address for the
784 first tunnel in direction node1->node2.
785 :param raddr_ip2: Policy selector remote IPv4 start address for the
786 first tunnel in direction node2->node1.
787 :param raddr_range: Mask specifying range of Policy selector Remote IPv4
788 addresses. Valid values are from 1 to 32.
790 :type interface1: str or int
791 :type interface2: str or int
793 :type crypto_alg: CryptoAlg
795 :type tunnel_ip1: str
796 :type tunnel_ip2: str
797 :type raddr_ip1: string
798 :type raddr_ip2: string
799 :type raddr_range: int
809 crypto_key = gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
810 integ_key = gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
812 IPsecUtil.vpp_ipsec_set_ip_route(
813 nodes['DUT1'], n_tunnels, tunnel_ip1, raddr_ip2, tunnel_ip2,
814 interface1, raddr_range)
815 IPsecUtil.vpp_ipsec_set_ip_route(
816 nodes['DUT2'], n_tunnels, tunnel_ip2, raddr_ip1, tunnel_ip1,
817 interface2, raddr_range)
819 IPsecUtil.vpp_ipsec_add_spd(
820 nodes['DUT1'], spd_id)
821 IPsecUtil.vpp_ipsec_spd_add_if(
822 nodes['DUT1'], spd_id, interface1)
823 IPsecUtil.vpp_ipsec_policy_add(
824 nodes['DUT1'], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
825 proto=50, laddr_range='100.0.0.0/8', raddr_range='100.0.0.0/8')
826 IPsecUtil.vpp_ipsec_policy_add(
827 nodes['DUT1'], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
828 proto=50, laddr_range='100.0.0.0/8', raddr_range='100.0.0.0/8')
830 IPsecUtil.vpp_ipsec_add_spd(
831 nodes['DUT2'], spd_id)
832 IPsecUtil.vpp_ipsec_spd_add_if(
833 nodes['DUT2'], spd_id, interface2)
834 IPsecUtil.vpp_ipsec_policy_add(
835 nodes['DUT2'], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
836 proto=50, laddr_range='100.0.0.0/8', raddr_range='100.0.0.0/8')
837 IPsecUtil.vpp_ipsec_policy_add(
838 nodes['DUT2'], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
839 proto=50, laddr_range='100.0.0.0/8', raddr_range='100.0.0.0/8')
841 IPsecUtil.vpp_ipsec_add_sad_entries(
842 nodes['DUT1'], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
843 integ_alg, integ_key, tunnel_ip1, tunnel_ip2)
845 IPsecUtil.vpp_ipsec_spd_add_entries(
846 nodes['DUT1'], n_tunnels, spd_id, p_lo, False, sa_id_1, raddr_ip2)
848 IPsecUtil.vpp_ipsec_add_sad_entries(
849 nodes['DUT2'], n_tunnels, sa_id_1, spi_1, crypto_alg, crypto_key,
850 integ_alg, integ_key, tunnel_ip1, tunnel_ip2)
852 IPsecUtil.vpp_ipsec_spd_add_entries(
853 nodes['DUT2'], n_tunnels, spd_id, p_lo, True, sa_id_1, raddr_ip2)
855 IPsecUtil.vpp_ipsec_add_sad_entries(
856 nodes['DUT2'], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
857 integ_alg, integ_key, tunnel_ip2, tunnel_ip1)
859 IPsecUtil.vpp_ipsec_spd_add_entries(
860 nodes['DUT2'], n_tunnels, spd_id, p_lo, False, sa_id_2, raddr_ip1)
862 IPsecUtil.vpp_ipsec_add_sad_entries(
863 nodes['DUT1'], n_tunnels, sa_id_2, spi_2, crypto_alg, crypto_key,
864 integ_alg, integ_key, tunnel_ip2, tunnel_ip1)
866 IPsecUtil.vpp_ipsec_spd_add_entries(
867 nodes['DUT1'], n_tunnels, spd_id, p_lo, True, sa_id_2, raddr_ip1)
870 def vpp_ipsec_show(node):
871 """Run "show ipsec" debug CLI command.
873 :param node: Node to run command on.
876 VatExecutor().execute_script('ipsec/ipsec_show.vat', node,