-# Copyright (c) 2021 Cisco and/or its affiliates.
-# Copyright (c) 2021 PANTHEON.tech s.r.o.
+# Copyright (c) 2022 Cisco and/or its affiliates.
+# Copyright (c) 2022 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:
src_addr = u""
dst_addr = u""
- cmd = u"ipsec_sad_entry_add_del_v2"
+ cmd = u"ipsec_sad_entry_add_del_v3"
err_msg = f"Failed to add Security Association Database entry " \
f"on host {node[u'host']}"
sad_entry = dict(
integrity_algorithm=integ_alg.alg_int_repr if integ_alg else 0,
integrity_key=ikey,
flags=flags,
- tunnel_src=str(src_addr),
- tunnel_dst=str(dst_addr),
- tunnel_flags=int(
- TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ tunnel=dict(
+ src=str(src_addr),
+ dst=str(dst_addr),
+ table_id=0,
+ encap_decap_flags=int(
+ TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ ),
+ dscp=int(IpDscp.IP_API_DSCP_CS0),
),
- 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
IPsecSadFlags.IPSEC_API_SAD_FLAG_IS_TUNNEL_V6
)
- cmd = u"ipsec_sad_entry_add_del_v2"
+ cmd = u"ipsec_sad_entry_add_del_v3"
err_msg = f"Failed to add Security Association Database entry " \
f"on host {node[u'host']}"
integrity_algorithm=integ_alg.alg_int_repr if integ_alg else 0,
integrity_key=ikey,
flags=flags,
- tunnel_src=str(src_addr),
- tunnel_dst=str(dst_addr),
- tunnel_flags=int(
- TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ tunnel=dict(
+ src=str(src_addr),
+ dst=str(dst_addr),
+ table_id=0,
+ encap_decap_flags=int(
+ TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ ),
+ dscp=int(IpDscp.IP_API_DSCP_CS0),
),
- 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
for i in range(n_entries):
args[u"entry"][u"sad_id"] = int(sad_id) + i
args[u"entry"][u"spi"] = int(spi) + i
- args[u"entry"][u"tunnel_src"] = str(src_addr + i * addr_incr) \
+ args[u"entry"][u"tunnel"][u"src"] = (
+ str(src_addr + i * addr_incr)
if tunnel_src and tunnel_dst else src_addr
- args[u"entry"][u"tunnel_dst"] = str(dst_addr + i * addr_incr) \
+ )
+ args[u"entry"][u"tunnel"][u"dst"] = (
+ str(dst_addr + i * addr_incr)
if tunnel_src and tunnel_dst else dst_addr
+ )
history = bool(not 1 < i < n_entries - 2)
papi_exec.add(cmd, history=history, **args)
papi_exec.get_replies(err_msg)
tunnel_src = ip_address(tunnel_src)
tunnel_dst = ip_address(tunnel_dst)
traffic_addr = ip_address(traffic_addr)
+ tunnel_dst_prefix = 128 if tunnel_dst.version == 6 else 32
addr_incr = 1 << (128 - raddr_range) if tunnel_src.version == 6 \
else 1 << (32 - raddr_range)
with open(tmp_filename, 'w') as tmp_file:
if_name = Topology.get_interface_name(node, interface)
for i in range(n_tunnels):
+ tunnel_dst_addr = tunnel_dst + i * addr_incr
conf = f"exec set interface ip address {if_name} " \
f"{tunnel_src + i * addr_incr}/{raddr_range}\n" \
f"exec ip route add {traffic_addr + i}/" \
- f"{128 if traffic_addr.version == 6 else 32} " \
- f"via {tunnel_dst + i * addr_incr} {if_name}\n"
+ f"{tunnel_dst_prefix} " \
+ f"via {tunnel_dst_addr} {if_name}\n" \
+ f"exec ip route add {tunnel_dst_addr}/" \
+ f"{tunnel_dst_prefix} " \
+ f"via {tunnel_dst_addr} {if_name}\n"
if dst_mac:
conf = f"{conf}exec set ip neighbor {if_name} " \
f"{tunnel_dst + i * addr_incr} {dst_mac}\n"
with PapiSocketExecutor(node) as papi_exec:
for i in range(n_tunnels):
+ tunnel_dst_addr = tunnel_dst + i * addr_incr
args1[u"prefix"] = IPUtil.create_prefix_object(
tunnel_src + i * addr_incr, raddr_range
)
args2[u"route"] = IPUtil.compose_vpp_route_structure(
node, traffic_addr + i,
- prefix_len=128 if traffic_addr.version == 6 else 32,
- interface=interface, gateway=tunnel_dst + i * addr_incr
+ prefix_len=tunnel_dst_prefix,
+ interface=interface, gateway=tunnel_dst_addr
)
history = bool(not 1 < i < n_tunnels - 2)
papi_exec.add(cmd1, history=history, **args1).\
add(cmd2, history=history, **args2)
+
+ args2[u"route"] = IPUtil.compose_vpp_route_structure(
+ node, tunnel_dst_addr,
+ prefix_len=tunnel_dst_prefix,
+ interface=interface, gateway=tunnel_dst_addr
+ )
+ papi_exec.add(cmd2, history=history, **args2)
+
if dst_mac:
args3[u"neighbor"][u"ip_address"] = ip_address(
- tunnel_dst + i * addr_incr
+ tunnel_dst_addr
)
papi_exec.add(cmd3, history=history, **args3)
papi_exec.get_replies(err_msg)
:type action: IPsecUtil.PolicyAction
:type inbound: bool
:type bidirectional: bool
- :raises NotImplemented: When the action is PolicyAction.PROTECT.
+ :raises NotImplementedError: When the action is PolicyAction.PROTECT.
"""
if action == PolicyAction.PROTECT:
- raise NotImplemented('Policy action PROTECT is not supported.')
+ raise NotImplementedError('Policy action PROTECT is not supported.')
spd_id_dir1 = 1
spd_id_dir2 = 2
tmp_filename = f"/tmp/ipsec_spd_{spd_id}_add_del_entry.script"
with open(tmp_filename, 'w') as tmp_file:
- for i in range(n_entries):
+ for _ in range(n_entries):
direction = u'inbound' if inbound else u'outbound'
sa = f' sa {sa_id.inc_fmt()}' if sa_id is not None else ''
protocol = f' protocol {protocol}' if proto else ''
os.remove(tmp_filename)
return
- for i in range(n_entries):
+ for _ in range(n_entries):
IPsecUtil.vpp_ipsec_add_spd_entry(
node, spd_id, next(priority), action, inbound,
next(sa_id) if sa_id is not None else sa_id,
# Configure IPSec SAD entries
ckeys = [bytes()] * existing_tunnels
ikeys = [bytes()] * existing_tunnels
- cmd = u"ipsec_sad_entry_add_del_v2"
+ cmd = u"ipsec_sad_entry_add_del_v3"
c_key = dict(
length=0,
data=None
integrity_algorithm=integ_alg.alg_int_repr if integ_alg else 0,
integrity_key=i_key,
flags=None,
- tunnel_src=0,
- tunnel_dst=0,
- tunnel_flags=int(
- TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ tunnel=dict(
+ src=0,
+ dst=0,
+ table_id=0,
+ encap_decap_flags=int(
+ TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ ),
+ dscp=int(IpDscp.IP_API_DSCP_CS0),
),
- dscp=int(IpDscp.IP_API_DSCP_CS0),
- table_id=0,
salt=0,
udp_src_port=IPSEC_UDP_PORT_NONE,
- udp_dst_port=IPSEC_UDP_PORT_NONE
+ udp_dst_port=IPSEC_UDP_PORT_NONE,
)
args = dict(
is_add=True,
]
)
# Configure IPSec SAD entries
- cmd = u"ipsec_sad_entry_add_del_v2"
+ cmd = u"ipsec_sad_entry_add_del_v3"
c_key = dict(
length=0,
data=None
sad_id=None,
spi=None,
protocol=int(IPsecProto.IPSEC_API_PROTO_ESP),
-
crypto_algorithm=crypto_alg.alg_int_repr,
crypto_key=c_key,
integrity_algorithm=integ_alg.alg_int_repr if integ_alg else 0,
integrity_key=i_key,
-
flags=None,
- tunnel_src=0,
- tunnel_dst=0,
- tunnel_flags=int(
- TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ tunnel=dict(
+ src=0,
+ dst=0,
+ table_id=0,
+ encap_decap_flags=int(
+ TunnelEncpaDecapFlags.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
+ ),
+ dscp=int(IpDscp.IP_API_DSCP_CS0),
),
- dscp=int(IpDscp.IP_API_DSCP_CS0),
- table_id=0,
salt=0,
udp_src_port=IPSEC_UDP_PORT_NONE,
- udp_dst_port=IPSEC_UDP_PORT_NONE
+ udp_dst_port=IPSEC_UDP_PORT_NONE,
)
args = dict(
is_add=True,
sa_id_2 = 200000
spi_1 = 300000
spi_2 = 400000
+ dut1_local_outbound_range = ip_network(f"{tunnel_ip1}/8", False).\
+ with_prefixlen
+ dut1_remote_outbound_range = ip_network(f"{tunnel_ip2}/8", False).\
+ with_prefixlen
crypto_key = gen_key(
IPsecUtil.get_crypto_alg_key_len(crypto_alg)
IPsecUtil.vpp_ipsec_spd_add_if(nodes[u"DUT1"], spd_id, interface1)
IPsecUtil.vpp_ipsec_add_spd_entry(
nodes[u"DUT1"], spd_id, p_hi, PolicyAction.BYPASS, inbound=False,
- proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
+ proto=50, laddr_range=dut1_local_outbound_range,
+ raddr_range=dut1_remote_outbound_range
)
IPsecUtil.vpp_ipsec_add_spd_entry(
nodes[u"DUT1"], spd_id, p_hi, PolicyAction.BYPASS, inbound=True,
- proto=50, laddr_range=u"100.0.0.0/8", raddr_range=u"100.0.0.0/8"
+ proto=50, laddr_range=dut1_remote_outbound_range,
+ raddr_range=dut1_local_outbound_range
)
IPsecUtil.vpp_ipsec_add_sad_entries(
)
if u"DUT2" in nodes.keys():
+ rmac = Topology.get_interface_mac(nodes[u"DUT1"], interface1)
IPsecUtil.vpp_ipsec_set_ip_route(
nodes[u"DUT2"], n_tunnels, tunnel_ip2, raddr_ip1, tunnel_ip1,
- interface2, raddr_range)
+ interface2, raddr_range, rmac)
IPsecUtil.vpp_ipsec_add_spd(nodes[u"DUT2"], spd_id)
IPsecUtil.vpp_ipsec_spd_add_if(nodes[u"DUT2"], spd_id, interface2)
IPsecUtil.vpp_ipsec_add_spd_entry(
nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS,
- inbound=False, proto=50, laddr_range=u"100.0.0.0/8",
- raddr_range=u"100.0.0.0/8"
+ inbound=False, proto=50, laddr_range=dut1_remote_outbound_range,
+ raddr_range=dut1_local_outbound_range
)
IPsecUtil.vpp_ipsec_add_spd_entry(
nodes[u"DUT2"], spd_id, p_hi, PolicyAction.BYPASS,
- inbound=True, proto=50, laddr_range=u"100.0.0.0/8",
- raddr_range=u"100.0.0.0/8"
+ inbound=True, proto=50, laddr_range=dut1_local_outbound_range,
+ raddr_range=dut1_remote_outbound_range
)
IPsecUtil.vpp_ipsec_add_sad_entries(
crypto_key, integ_alg, integ_key, tunnel_ip1, tunnel_ip2
)
IPsecUtil.vpp_ipsec_add_spd_entries(
- nodes[u"DUT2"], n_tunnels, spd_id, priority=ObjIncrement(p_lo, 0),
+ nodes[u"DUT2"], n_tunnels, spd_id,
+ priority=ObjIncrement(p_lo, 0),
action=PolicyAction.PROTECT, inbound=True,
sa_id=ObjIncrement(sa_id_1, 1),
raddr_range=NetworkIncrement(ip_network(raddr_ip2))
crypto_key, integ_alg, integ_key, tunnel_ip2, tunnel_ip1
)
IPsecUtil.vpp_ipsec_add_spd_entries(
- nodes[u"DUT2"], n_tunnels, spd_id, priority=ObjIncrement(p_lo, 0),
+ nodes[u"DUT2"], n_tunnels, spd_id,
+ priority=ObjIncrement(p_lo, 0),
action=PolicyAction.PROTECT, inbound=False,
sa_id=ObjIncrement(sa_id_2, 1),
raddr_range=NetworkIncrement(ip_network(raddr_ip1))
:type node: dict
"""
cmds = [
- u"ipsec_sa_v2_dump"
+ u"ipsec_sa_v3_dump"
]
PapiSocketExecutor.dump_and_log(node, cmds)