-# Copyright (c) 2023 Cisco and/or its affiliates.
-# Copyright (c) 2023 PANTHEON.tech s.r.o.
+# Copyright (c) 2024 Cisco and/or its affiliates.
+# Copyright (c) 2024 PANTHEON.tech s.r.o.
# 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:
"""IPsec utilities library."""
-import os
-
from enum import Enum, IntEnum
from io import open
from ipaddress import ip_network, ip_address
from resources.libraries.python.FlowUtil import FlowUtil
-IPSEC_UDP_PORT_NONE = 0xffff
+IPSEC_UDP_PORT_DEFAULT = 4500
+IPSEC_REPLAY_WINDOW_DEFAULT = 64
def gen_key(length):
def vpp_ipsec_set_async_mode(node, async_enable=1):
"""Set IPsec async mode on|off.
+ Unconditionally, attempt to switch crypto dispatch into polling mode.
+
:param node: VPP node to set IPsec async mode.
:param async_enable: Async mode on or off.
:type node: dict
:raises RuntimeError: If failed to set IPsec async mode or if no API
reply received.
"""
- cmd = u"ipsec_set_async_mode"
- err_msg = f"Failed to set IPsec async mode on host {node[u'host']}"
- args = dict(
- async_enable=async_enable
- )
with PapiSocketExecutor(node) as papi_exec:
+ cmd = u"ipsec_set_async_mode"
+ err_msg = f"Failed to set IPsec async mode on host {node[u'host']}"
+ args = dict(
+ async_enable=async_enable
+ )
papi_exec.add(cmd, **args).get_reply(err_msg)
+ cmd = "crypto_set_async_dispatch_v2"
+ err_msg = "Failed to set dispatch mode."
+ args = dict(mode=0, adaptive=False)
+ try:
+ papi_exec.add(cmd, **args).get_reply(err_msg)
+ except (AttributeError, RuntimeError):
+ # Expected when VPP build does not have the _v2 yet
+ # (after and before the first CRC check).
+ # TODO: Fail here when testing of pre-23.10 builds is over.
+ pass
@staticmethod
def vpp_ipsec_crypto_sw_scheduler_set_worker(
src_addr = u""
dst_addr = u""
- cmd = u"ipsec_sad_entry_add"
+ cmd = u"ipsec_sad_entry_add_v2"
err_msg = f"Failed to add Security Association Database entry " \
f"on host {node[u'host']}"
sad_entry = dict(
dscp=int(IpDscp.IP_API_DSCP_CS0),
),
protocol=int(IPsecProto.IPSEC_API_PROTO_ESP),
- udp_src_port=4500, # default value in api
- udp_dst_port=4500 # default value in api
+ udp_src_port=IPSEC_UDP_PORT_DEFAULT,
+ udp_dst_port=IPSEC_UDP_PORT_DEFAULT,
+ anti_replay_window_size=IPSEC_REPLAY_WINDOW_DEFAULT,
)
args = dict(entry=sad_entry)
with PapiSocketExecutor(node) as papi_exec:
@staticmethod
def vpp_ipsec_add_sad_entries(
node, n_entries, sad_id, spi, crypto_alg, crypto_key,
- integ_alg=None, integ_key=u"", tunnel_src=None,tunnel_dst=None,
+ integ_alg=None, integ_key=u"", tunnel_src=None, tunnel_dst=None,
tunnel_addr_incr=True):
"""Create multiple Security Association Database entries on VPP node.
IPsecSadFlags.IPSEC_API_SAD_FLAG_IS_TUNNEL_V6
)
- cmd = u"ipsec_sad_entry_add"
+ cmd = u"ipsec_sad_entry_add_v2"
err_msg = f"Failed to add Security Association Database entry " \
f"on host {node[u'host']}"
dscp=int(IpDscp.IP_API_DSCP_CS0),
),
protocol=int(IPsecProto.IPSEC_API_PROTO_ESP),
- udp_src_port=4500, # default value in api
- udp_dst_port=4500, # default value in api
+ udp_src_port=IPSEC_UDP_PORT_DEFAULT,
+ udp_dst_port=IPSEC_UDP_PORT_DEFAULT,
+ anti_replay_window_size=IPSEC_REPLAY_WINDOW_DEFAULT,
)
args = dict(entry=sad_entry)
with PapiSocketExecutor(node, is_async=True) as papi_exec:
# Configure IPSec SAD entries
ckeys = [bytes()] * existing_tunnels
ikeys = [bytes()] * existing_tunnels
- cmd = u"ipsec_sad_entry_add"
+ cmd = u"ipsec_sad_entry_add_v2"
c_key = dict(
length=0,
data=None
dscp=int(IpDscp.IP_API_DSCP_CS0),
),
salt=0,
- udp_src_port=IPSEC_UDP_PORT_NONE,
- udp_dst_port=IPSEC_UDP_PORT_NONE,
+ udp_src_port=IPSEC_UDP_PORT_DEFAULT,
+ udp_dst_port=IPSEC_UDP_PORT_DEFAULT,
+ anti_replay_window_size=IPSEC_REPLAY_WINDOW_DEFAULT,
)
args = dict(entry=sad_entry)
for i in range(existing_tunnels, n_tunnels):
]
)
# Configure IPSec SAD entries
- cmd = u"ipsec_sad_entry_add"
+ cmd = u"ipsec_sad_entry_add_v2"
c_key = dict(
length=0,
data=None
dscp=int(IpDscp.IP_API_DSCP_CS0),
),
salt=0,
- udp_src_port=IPSEC_UDP_PORT_NONE,
- udp_dst_port=IPSEC_UDP_PORT_NONE,
+ udp_src_port=IPSEC_UDP_PORT_DEFAULT,
+ udp_dst_port=IPSEC_UDP_PORT_DEFAULT,
+ anti_replay_window_size=IPSEC_REPLAY_WINDOW_DEFAULT,
)
args = dict(entry=sad_entry)
for i in range(existing_tunnels, n_tunnels):
for i in range(n_tunnels//(addr_incr**2)+1):
dut1_local_outbound_range = \
ip_network(f"{ip_address(tunnel_ip1) + i*(addr_incr**3)}/8",
- False).with_prefixlen
+ False).with_prefixlen
dut1_remote_outbound_range = \
ip_network(f"{ip_address(tunnel_ip2) + i*(addr_incr**3)}/8",
- False).with_prefixlen
+ False).with_prefixlen
IPsecUtil.vpp_ipsec_add_spd_entry(
nodes[u"DUT1"], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
for i in range(n_tunnels//(addr_incr**2)+1):
dut2_local_outbound_range = \
ip_network(f"{ip_address(tunnel_ip1) + i*(addr_incr**3)}/8",
- False).with_prefixlen
+ False).with_prefixlen
dut2_remote_outbound_range = \
ip_network(f"{ip_address(tunnel_ip2) + i*(addr_incr**3)}/8",
- False).with_prefixlen
+ False).with_prefixlen
IPsecUtil.vpp_ipsec_add_spd_entry(
nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS,
- inbound=False, proto=50, laddr_range=dut2_remote_outbound_range,
+ inbound=False, proto=50,
+ laddr_range=dut2_remote_outbound_range,
raddr_range=dut2_local_outbound_range
)
IPsecUtil.vpp_ipsec_add_spd_entry(
nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS,
- inbound=True, proto=50, laddr_range=dut2_local_outbound_range,
+ inbound=True, proto=50,
+ laddr_range=dut2_local_outbound_range,
raddr_range=dut2_remote_outbound_range
)
:param node: DUT node.
:type node: dict
"""
- cmds = [
- u"ipsec_sa_v3_dump"
- ]
- PapiSocketExecutor.dump_and_log(node, cmds)
+ cmd = "ipsec_sa_v5_dump"
+ PapiSocketExecutor.dump_and_log(node, [cmd])
@staticmethod
def vpp_ipsec_flow_enale_rss(node, proto, type, function="default"):
for i in range(0, n_flows):
rx_queue = i%rx_queues
-
spi = spi_start + i
flow_index = FlowUtil.vpp_create_ip4_ipsec_flow(
- node, "ESP", spi, "redirect-to-queue", value=rx_queue)
+ node, "ESP", spi, "redirect-to-queue", value=rx_queue)
FlowUtil.vpp_flow_enable(node, interface, flow_index)