From 17dcec0b940374127f6e1e004fb3ec261a0a3709 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 9 Jan 2019 21:22:20 -0800 Subject: [PATCH] IPSEC: API modernisation - use enums to enumerate the algoritms and protocols that are supported - use address_t types to simplify encode/deocde - use typedefs of entry objects to get consistency between add/del API and dump Change-Id: I7e7c58c06a150e2439633ba9dca58bc1049677ee Signed-off-by: Neale Ranns --- src/vat/api_format.c | 369 ++++++++++++++++++--------------------------- src/vnet/ipsec/ipsec.api | 334 ++++++++++++++++++++++------------------ src/vnet/ipsec/ipsec.h | 6 +- src/vnet/ipsec/ipsec_api.c | 313 +++++++++++++++++++++++++------------- test/template_ipsec.py | 77 ++++++---- test/test_ipsec_ah.py | 28 +++- test/test_ipsec_api.py | 23 +-- test/test_ipsec_esp.py | 27 +++- test/test_ipsec_nat.py | 14 +- test/vpp_ipsec.py | 80 +++++----- test/vpp_papi_provider.py | 94 ++++++------ 11 files changed, 735 insertions(+), 630 deletions(-) diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 85bf9d0731a..3755354924d 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -361,20 +361,6 @@ unformat_ipsec_policy_action (unformat_input_t * input, va_list * args) return 1; } -uword -unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args) -{ - u32 *r = va_arg (*args, u32 *); - - if (0); -#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f; - foreach_ipsec_crypto_alg -#undef _ - else - return 0; - return 1; -} - u8 * format_ipsec_crypto_alg (u8 * s, va_list * args) { @@ -392,20 +378,6 @@ format_ipsec_crypto_alg (u8 * s, va_list * args) return format (s, "%s", t); } -uword -unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args) -{ - u32 *r = va_arg (*args, u32 *); - - if (0); -#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f; - foreach_ipsec_integ_alg -#undef _ - else - return 0; - return 1; -} - u8 * format_ipsec_integ_alg (u8 * s, va_list * args) { @@ -473,6 +445,34 @@ api_unformat_hw_if_index (unformat_input_t * input, va_list * args) #endif /* VPP_API_TEST_BUILTIN */ +uword +unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args) +{ + u32 *r = va_arg (*args, u32 *); + + if (0); +#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f; + foreach_ipsec_crypto_alg +#undef _ + else + return 0; + return 1; +} + +uword +unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args) +{ + u32 *r = va_arg (*args, u32 *); + + if (0); +#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f; + foreach_ipsec_integ_alg +#undef _ + else + return 0; + return 1; +} + static uword unformat_policer_rate_type (unformat_input_t * input, va_list * args) { @@ -5208,8 +5208,8 @@ _(want_l2_macs_events_reply) \ _(input_acl_set_interface_reply) \ _(ipsec_spd_add_del_reply) \ _(ipsec_interface_add_del_spd_reply) \ -_(ipsec_spd_add_del_entry_reply) \ -_(ipsec_sad_add_del_entry_reply) \ +_(ipsec_spd_entry_add_del_reply) \ +_(ipsec_sad_entry_add_del_reply) \ _(ipsec_sa_set_key_reply) \ _(ipsec_tunnel_if_add_del_reply) \ _(ipsec_tunnel_if_set_key_reply) \ @@ -5463,8 +5463,8 @@ _(IP_ADDRESS_DETAILS, ip_address_details) \ _(IP_DETAILS, ip_details) \ _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \ _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \ -_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \ -_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \ +_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply) \ +_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply) \ _(IPSEC_SA_DETAILS, ipsec_sa_details) \ _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \ _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply) \ @@ -14829,26 +14829,24 @@ api_ipsec_interface_add_del_spd (vat_main_t * vam) } static int -api_ipsec_spd_add_del_entry (vat_main_t * vam) +api_ipsec_spd_entry_add_del (vat_main_t * vam) { unformat_input_t *i = vam->input; - vl_api_ipsec_spd_add_del_entry_t *mp; + vl_api_ipsec_spd_entry_add_del_t *mp; u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1; u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0; i32 priority = 0; u32 rport_start = 0, rport_stop = (u32) ~ 0; u32 lport_start = 0, lport_stop = (u32) ~ 0; - ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop; - ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop; + vl_api_address_t laddr_start = { }, laddr_stop = + { + }, raddr_start = + { + }, raddr_stop = + { + }; int ret; - laddr4_start.as_u32 = raddr4_start.as_u32 = 0; - laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0; - laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0; - laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0; - laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0; - laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0; - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { if (unformat (i, "del")) @@ -14873,58 +14871,18 @@ api_ipsec_spd_add_del_entry (vat_main_t * vam) ; else if (unformat (i, "rport_stop %d", &rport_stop)) ; - else - if (unformat - (i, "laddr_start %U", unformat_ip4_address, &laddr4_start)) - { - is_ipv6 = 0; - is_ip_any = 0; - } - else - if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop)) - { - is_ipv6 = 0; - is_ip_any = 0; - } - else - if (unformat - (i, "raddr_start %U", unformat_ip4_address, &raddr4_start)) - { - is_ipv6 = 0; - is_ip_any = 0; - } - else - if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop)) - { - is_ipv6 = 0; - is_ip_any = 0; - } - else - if (unformat - (i, "laddr_start %U", unformat_ip6_address, &laddr6_start)) - { - is_ipv6 = 1; - is_ip_any = 0; - } - else - if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop)) - { - is_ipv6 = 1; - is_ip_any = 0; - } - else - if (unformat - (i, "raddr_start %U", unformat_ip6_address, &raddr6_start)) - { - is_ipv6 = 1; - is_ip_any = 0; - } - else - if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop)) - { - is_ipv6 = 1; - is_ip_any = 0; - } + else if (unformat (i, "laddr_start %U", + unformat_vl_api_address, &laddr_start)) + is_ip_any = 0; + else if (unformat (i, "laddr_stop %U", unformat_vl_api_address, + &laddr_stop)) + is_ip_any = 0; + else if (unformat (i, "raddr_start %U", unformat_vl_api_address, + &raddr_start)) + is_ip_any = 0; + else if (unformat (i, "raddr_stop %U", unformat_vl_api_address, + &raddr_stop)) + is_ip_any = 0; else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy)) { @@ -14942,65 +14900,51 @@ api_ipsec_spd_add_del_entry (vat_main_t * vam) } - M (IPSEC_SPD_ADD_DEL_ENTRY, mp); + M (IPSEC_SPD_ENTRY_ADD_DEL, mp); - mp->spd_id = ntohl (spd_id); - mp->priority = ntohl (priority); - mp->is_outbound = is_outbound; - - mp->is_ipv6 = is_ipv6; - if (is_ipv6 || is_ip_any) - { - clib_memcpy (mp->remote_address_start, &raddr6_start, - sizeof (ip6_address_t)); - clib_memcpy (mp->remote_address_stop, &raddr6_stop, - sizeof (ip6_address_t)); - clib_memcpy (mp->local_address_start, &laddr6_start, - sizeof (ip6_address_t)); - clib_memcpy (mp->local_address_stop, &laddr6_stop, - sizeof (ip6_address_t)); - } - else - { - clib_memcpy (mp->remote_address_start, &raddr4_start, - sizeof (ip4_address_t)); - clib_memcpy (mp->remote_address_stop, &raddr4_stop, - sizeof (ip4_address_t)); - clib_memcpy (mp->local_address_start, &laddr4_start, - sizeof (ip4_address_t)); - clib_memcpy (mp->local_address_stop, &laddr4_stop, - sizeof (ip4_address_t)); - } - mp->protocol = (u8) protocol; - mp->local_port_start = ntohs ((u16) lport_start); - mp->local_port_stop = ntohs ((u16) lport_stop); - mp->remote_port_start = ntohs ((u16) rport_start); - mp->remote_port_stop = ntohs ((u16) rport_stop); - mp->policy = (u8) policy; - mp->sa_id = ntohl (sa_id); mp->is_add = is_add; - mp->is_ip_any = is_ip_any; + + mp->entry.spd_id = ntohl (spd_id); + mp->entry.priority = ntohl (priority); + mp->entry.is_outbound = is_outbound; + + clib_memcpy (&mp->entry.remote_address_start, &raddr_start, + sizeof (vl_api_address_t)); + clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop, + sizeof (vl_api_address_t)); + clib_memcpy (&mp->entry.local_address_start, &laddr_start, + sizeof (vl_api_address_t)); + clib_memcpy (&mp->entry.local_address_stop, &laddr_stop, + sizeof (vl_api_address_t)); + + mp->entry.protocol = (u8) protocol; + mp->entry.local_port_start = ntohs ((u16) lport_start); + mp->entry.local_port_stop = ntohs ((u16) lport_stop); + mp->entry.remote_port_start = ntohs ((u16) rport_start); + mp->entry.remote_port_stop = ntohs ((u16) rport_stop); + mp->entry.policy = (u8) policy; + mp->entry.sa_id = ntohl (sa_id); + mp->entry.is_ip_any = is_ip_any; + S (mp); W (ret); return ret; } static int -api_ipsec_sad_add_del_entry (vat_main_t * vam) +api_ipsec_sad_entry_add_del (vat_main_t * vam) { unformat_input_t *i = vam->input; - vl_api_ipsec_sad_add_del_entry_t *mp; + vl_api_ipsec_sad_entry_add_del_t *mp; u32 sad_id = 0, spi = 0; u8 *ck = 0, *ik = 0; u8 is_add = 1; - u8 protocol = IPSEC_PROTOCOL_AH; - u8 is_tunnel = 0, is_tunnel_ipv6 = 0; - u32 crypto_alg = 0, integ_alg = 0; - ip4_address_t tun_src4; - ip4_address_t tun_dst4; - ip6_address_t tun_src6; - ip6_address_t tun_dst6; + vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE; + vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE; + vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE; + vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH; + vl_api_address_t tun_src, tun_dst; int ret; while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) @@ -15012,51 +14956,30 @@ api_ipsec_sad_add_del_entry (vat_main_t * vam) else if (unformat (i, "spi %d", &spi)) ; else if (unformat (i, "esp")) - protocol = IPSEC_PROTOCOL_ESP; - else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) - { - is_tunnel = 1; - is_tunnel_ipv6 = 0; - } - else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) - { - is_tunnel = 1; - is_tunnel_ipv6 = 0; - } - else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) - { - is_tunnel = 1; - is_tunnel_ipv6 = 1; - } - else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) + protocol = IPSEC_API_PROTO_ESP; + else + if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src)) { - is_tunnel = 1; - is_tunnel_ipv6 = 1; + flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL; + if (ADDRESS_IP6 == tun_src.af) + flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6; } else - if (unformat - (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) + if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst)) { - if (crypto_alg >= IPSEC_CRYPTO_N_ALG) - { - clib_warning ("unsupported crypto-alg: '%U'", - format_ipsec_crypto_alg, crypto_alg); - return -99; - } + flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL; + if (ADDRESS_IP6 == tun_src.af) + flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6; } + else + if (unformat (i, "crypto_alg %U", + unformat_ipsec_api_crypto_alg, &crypto_alg)) + ; else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck)) ; - else - if (unformat - (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) - { - if (integ_alg >= IPSEC_INTEG_N_ALG) - { - clib_warning ("unsupported integ-alg: '%U'", - format_ipsec_integ_alg, integ_alg); - return -99; - } - } + else if (unformat (i, "integ_alg %U", + unformat_ipsec_api_integ_alg, &integ_alg)) + ; else if (unformat (i, "integ_key %U", unformat_hex_string, &ik)) ; else @@ -15067,46 +14990,37 @@ api_ipsec_sad_add_del_entry (vat_main_t * vam) } - M (IPSEC_SAD_ADD_DEL_ENTRY, mp); + M (IPSEC_SAD_ENTRY_ADD_DEL, mp); - mp->sad_id = ntohl (sad_id); mp->is_add = is_add; - mp->protocol = protocol; - mp->spi = ntohl (spi); - mp->is_tunnel = is_tunnel; - mp->is_tunnel_ipv6 = is_tunnel_ipv6; - mp->crypto_algorithm = crypto_alg; - mp->integrity_algorithm = integ_alg; - mp->crypto_key_length = vec_len (ck); - mp->integrity_key_length = vec_len (ik); + mp->entry.sad_id = ntohl (sad_id); + mp->entry.protocol = protocol; + mp->entry.spi = ntohl (spi); + mp->entry.flags = flags; + + mp->entry.crypto_algorithm = crypto_alg; + mp->entry.integrity_algorithm = integ_alg; + mp->entry.crypto_key.length = vec_len (ck); + mp->entry.integrity_key.length = vec_len (ik); - if (mp->crypto_key_length > sizeof (mp->crypto_key)) - mp->crypto_key_length = sizeof (mp->crypto_key); + if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data)) + mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data); - if (mp->integrity_key_length > sizeof (mp->integrity_key)) - mp->integrity_key_length = sizeof (mp->integrity_key); + if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data)) + mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data); if (ck) - clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length); + clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length); if (ik) - clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length); + clib_memcpy (mp->entry.integrity_key.data, ik, + mp->entry.integrity_key.length); - if (is_tunnel) + if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL) { - if (is_tunnel_ipv6) - { - clib_memcpy (mp->tunnel_src_address, &tun_src6, - sizeof (ip6_address_t)); - clib_memcpy (mp->tunnel_dst_address, &tun_dst6, - sizeof (ip6_address_t)); - } - else - { - clib_memcpy (mp->tunnel_src_address, &tun_src4, - sizeof (ip4_address_t)); - clib_memcpy (mp->tunnel_dst_address, &tun_dst4, - sizeof (ip4_address_t)); - } + clib_memcpy (&mp->entry.tunnel_src, &tun_src, + sizeof (mp->entry.tunnel_src)); + clib_memcpy (&mp->entry.tunnel_dst, &tun_dst, + sizeof (mp->entry.tunnel_dst)); } S (mp); @@ -15141,19 +15055,19 @@ api_ipsec_sa_set_key (vat_main_t * vam) M (IPSEC_SA_SET_KEY, mp); mp->sa_id = ntohl (sa_id); - mp->crypto_key_length = vec_len (ck); - mp->integrity_key_length = vec_len (ik); + mp->crypto_key.length = vec_len (ck); + mp->integrity_key.length = vec_len (ik); - if (mp->crypto_key_length > sizeof (mp->crypto_key)) - mp->crypto_key_length = sizeof (mp->crypto_key); + if (mp->crypto_key.length > sizeof (mp->crypto_key.data)) + mp->crypto_key.length = sizeof (mp->crypto_key.data); - if (mp->integrity_key_length > sizeof (mp->integrity_key)) - mp->integrity_key_length = sizeof (mp->integrity_key); + if (mp->integrity_key.length > sizeof (mp->integrity_key.data)) + mp->integrity_key.length = sizeof (mp->integrity_key.data); if (ck) - clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length); + clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length); if (ik) - clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length); + clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length); S (mp); W (ret); @@ -15205,7 +15119,7 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam) ; else if (unformat - (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) + (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg)) { if (crypto_alg >= IPSEC_CRYPTO_N_ALG) { @@ -15216,7 +15130,7 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam) } else if (unformat - (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) + (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg)) { if (integ_alg >= IPSEC_INTEG_N_ALG) { @@ -15427,15 +15341,20 @@ api_ipsec_tunnel_if_set_key (vat_main_t * vam) if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) ; else - if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg)) + if (unformat + (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg)) key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO; else - if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg)) + if (unformat + (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg)) key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO; - else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg)) + else + if (unformat + (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg)) key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG; else - if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg)) + if (unformat + (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg)) key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG; else if (unformat (i, "%U", unformat_hex_string, &key)) ; @@ -23239,10 +23158,10 @@ _(ip_dump, "ipv4 | ipv6") \ _(ipsec_spd_add_del, "spd_id [del]") \ _(ipsec_interface_add_del_spd, "( | sw_if_index )\n" \ " spid_id ") \ -_(ipsec_sad_add_del_entry, "sad_id spi crypto_alg \n" \ +_(ipsec_sad_entry_add_del, "sad_id spi crypto_alg \n" \ " crypto_key tunnel_src tunnel_dst \n" \ " integ_alg integ_key ") \ -_(ipsec_spd_add_del_entry, "spd_id priority action \n" \ +_(ipsec_spd_entry_add_del, "spd_id priority action \n" \ " (inbound|outbound) [sa_id ] laddr_start \n" \ " laddr_stop raddr_start raddr_stop \n" \ " [lport_start lport_stop ] [rport_start rport_stop ]" ) \ diff --git a/src/vnet/ipsec/ipsec.api b/src/vnet/ipsec/ipsec.api index 2b015f9c223..92c39acefd6 100644 --- a/src/vnet/ipsec/ipsec.api +++ b/src/vnet/ipsec/ipsec.api @@ -1,3 +1,4 @@ +/* Hey Emacs use -*- mode: C -*- */ /* * Copyright (c) 2015-2016 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,7 +14,9 @@ * limitations under the License. */ -option version = "2.1.0"; +option version = "3.0.0"; + +import "vnet/ip/ip_types.api"; /** \brief IPsec: Add/delete Security Policy Database @param client_index - opaque cookie to identify the sender @@ -50,121 +53,236 @@ autoreply define ipsec_interface_add_del_spd u32 spd_id; }; -/** \brief IPsec: Add/delete Security Policy Database entry + +enum ipsec_spd_action +{ + /* bypass - no IPsec processing */ + IPSEC_API_SPD_ACTION_BYPASS = 0, + /* discard - discard packet with ICMP processing */ + IPSEC_API_SPD_ACTION_DISCARD, + /* resolve - send request to control plane for SA resolving */ + IPSEC_API_SPD_ACTION_RESOLVE, + /* protect - apply IPsec policy using following parameters */ + IPSEC_API_SPD_ACTION_PROTECT, +}; + +/** \brief IPsec: Security Policy Database entry See RFC 4301, 4.4.1.1 on how to match packet to selectors - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - add SPD if non-zero, else delete @param spd_id - SPD instance id (control plane allocated) @param priority - priority of SPD entry (non-unique value). Used to order SPD matching - higher priorities match before lower @param is_outbound - entry applies to outbound traffic if non-zero, otherwise applies to inbound traffic - @param is_ipv6 - remote/local address are IPv6 if non-zero, else IPv4 @param remote_address_start - start of remote address range to match @param remote_address_stop - end of remote address range to match @param local_address_start - start of local address range to match @param local_address_stop - end of local address range to match - @param protocol - protocol type to match [0 means any] + @param protocol - protocol type to match [0 means any] otherwise IANA value @param remote_port_start - start of remote port range to match ... @param remote_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] @param local_port_start - start of local port range to match ... @param local_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] - @param policy - 0 = bypass (no IPsec processing), 1 = discard (discard packet with ICMP processing), 2 = resolve (send request to control plane for SA resolving, and discard without ICMP processing), 3 = protect (apply IPsec policy using following parameters) + @param policy - action to perform on match @param sa_id - SAD instance id (control plane allocated) - */ - -autoreply define ipsec_spd_add_del_entry +typedef ipsec_spd_entry { - u32 client_index; - u32 context; - u8 is_add; - u32 spd_id; i32 priority; u8 is_outbound; + u32 sa_id; + vl_api_ipsec_spd_action_t policy; + u8 protocol; + // Selector - u8 is_ipv6; u8 is_ip_any; - u8 remote_address_start[16]; - u8 remote_address_stop[16]; - u8 local_address_start[16]; - u8 local_address_stop[16]; - - u8 protocol; + vl_api_address_t remote_address_start; + vl_api_address_t remote_address_stop; + vl_api_address_t local_address_start; + vl_api_address_t local_address_stop; u16 remote_port_start; u16 remote_port_stop; u16 local_port_start; u16 local_port_stop; +}; - // Policy - u8 policy; - u32 sa_id; +/** \brief IPsec: Add/delete Security Policy Database entry + + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add SPD if non-zero, else delete + @param entry - Description of the entry to add/dell +*/ +autoreply define ipsec_spd_entry_add_del +{ + u32 client_index; + u32 context; + u8 is_add; + vl_api_ipsec_spd_entry_t entry; }; -/** \brief IPsec: Add/delete Security Association Database entry +/** \brief Dump IPsec all SPD IDs @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param is_add - add SAD entry if non-zero, else delete +*/ +define ipsec_spds_dump { + u32 client_index; + u32 context; +}; - @param sad_id - sad id +/** \brief Dump IPsec all SPD IDs response + @param client_index - opaque cookie to identify the sender + @param spd_id - SPD instance id (control plane allocated) + @param npolicies - number of policies in SPD +*/ +define ipsec_spds_details { + u32 context; + u32 spd_id; + u32 npolicies; +}; - @param spi - security parameter index +/** \brief Dump ipsec policy database data + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param spd_id - SPD instance id + @param sa_id - SA id, optional, set to ~0 to see all policies in SPD +*/ +define ipsec_spd_dump { + u32 client_index; + u32 context; + u32 spd_id; + u32 sa_id; +}; - @param protocol - 0 = AH, 1 = ESP +/** \brief IPsec policy database response + @param context - sender context which was passed in the request + €param entry - The SPD entry. + @param bytes - byte count of packets matching this policy + @param packets - count of packets matching this policy +*/ +define ipsec_spd_details { + u32 context; + vl_api_ipsec_spd_entry_t entry; + u64 bytes; + u64 packets; +}; - @param crypto_algorithm - 0 = Null, 1 = AES-CBC-128, 2 = AES-CBC-192, 3 = AES-CBC-256, 4 = 3DES-CBC - @param crypto_key_length - length of crypto_key in bytes - @param crypto_key - crypto keying material +/* + * @brief Support cryptographic algorithms + */ +enum ipsec_crypto_alg +{ + IPSEC_API_CRYPTO_ALG_NONE = 0, + IPSEC_API_CRYPTO_ALG_AES_CBC_128, + IPSEC_API_CRYPTO_ALG_AES_CBC_192, + IPSEC_API_CRYPTO_ALG_AES_CBC_256, + IPSEC_API_CRYPTO_ALG_AES_CTR_128, + IPSEC_API_CRYPTO_ALG_AES_CTR_192, + IPSEC_API_CRYPTO_ALG_AES_CTR_256, + IPSEC_API_CRYPTO_ALG_AES_GCM_128, + IPSEC_API_CRYPTO_ALG_AES_GCM_192, + IPSEC_API_CRYPTO_ALG_AES_GCM_256, + IPSEC_API_CRYPTO_ALG_DES_CBC, + IPSEC_API_CRYPTO_ALG_3DES_CBC, +}; - @param integrity_algorithm - 0 = None, 1 = MD5-96, 2 = SHA1-96, 3 = SHA-256, 4 = SHA-384, 5=SHA-512 - @param integrity_key_length - length of integrity_key in bytes - @param integrity_key - integrity keying material +/* + * @brief Supported Integrity Algorithms + */ +enum ipsec_integ_alg +{ + IPSEC_API_INTEG_ALG_NONE = 0, + /* RFC2403 */ + IPSEC_API_INTEG_ALG_MD5_96, + /* RFC2404 */ + IPSEC_API_INTEG_ALG_SHA1_96, + /* draft-ietf-ipsec-ciph-sha-256-00 */ + IPSEC_API_INTEG_ALG_SHA_256_96, + /* RFC4868 */ + IPSEC_API_INTEG_ALG_SHA_256_128, + /* RFC4868 */ + IPSEC_API_INTEG_ALG_SHA_384_192, + /* RFC4868 */ + IPSEC_API_INTEG_ALG_SHA_512_256, +}; + +enum ipsec_sad_flags +{ + IPSEC_API_SAD_FLAG_NONE = 0, + /* Enable extended sequence numbers */ + IPSEC_API_SAD_FLAG_USE_EXTENDED_SEQ_NUM = 0x01, + /* Enable Anti-replay */ + IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY = 0x02, + /* IPsec tunnel mode if non-zero, else transport mode */ + IPSEC_API_SAD_FLAG_IS_TUNNEL = 0x04, + /* IPsec tunnel mode is IPv6 if non-zero, + * else IPv4 tunnel only valid if is_tunnel is non-zero */ + IPSEC_API_SAD_FLAG_IS_TUNNEL_V6 = 0x08, + /* enable UDP encapsulation for NAT traversal */ + IPSEC_API_SAD_FLAG_UDP_ENCAP = 0x10, +}; + +enum ipsec_proto +{ + IPSEC_API_PROTO_ESP, + IPSEC_API_PROTO_AH, +}; - @param use_extended_sequence_number - use ESN when non-zero +typedef key +{ + /* the length of the key */ + u8 length; + /* The data for the key */ + u8 data[128]; +}; - @param is_tunnel - IPsec tunnel mode if non-zero, else transport mode - @param is_tunnel_ipv6 - IPsec tunnel mode is IPv6 if non-zero, else IPv4 tunnel only valid if is_tunnel is non-zero +/** \brief IPsec: Security Association Database entry + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add SAD entry if non-zero, else delete + @param sad_id - sad id + @param spi - security parameter index + @param protocol - 0 = AH, 1 = ESP + @param crypto_algorithm - a supported crypto algorithm + @param crypto_key - crypto keying material + @param integrity_algorithm - one of the supported algorithms + @param integrity_key - integrity keying material @param tunnel_src_address - IPsec tunnel source address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero @param tunnel_dst_address - IPsec tunnel destination address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero - @param udp_encap - enable UDP encapsulation for NAT traversal - - To be added: - Anti-replay - IPsec tunnel address copy mode (to support GDOI) */ - -autoreply define ipsec_sad_add_del_entry +typedef ipsec_sad_entry { - u32 client_index; - u32 context; - u8 is_add; - u32 sad_id; u32 spi; - u8 protocol; + vl_api_ipsec_proto_t protocol; - u8 crypto_algorithm; - u8 crypto_key_length; - u8 crypto_key[128]; + vl_api_ipsec_crypto_alg_t crypto_algorithm; + vl_api_key_t crypto_key; - u8 integrity_algorithm; - u8 integrity_key_length; - u8 integrity_key[128]; + vl_api_ipsec_integ_alg_t integrity_algorithm; + vl_api_key_t integrity_key; - u8 use_extended_sequence_number; - u8 use_anti_replay; + vl_api_ipsec_sad_flags_t flags; - u8 is_tunnel; - u8 is_tunnel_ipv6; - u8 tunnel_src_address[16]; - u8 tunnel_dst_address[16]; - u8 udp_encap; + vl_api_address_t tunnel_src; + vl_api_address_t tunnel_dst; +}; + +/** \brief IPsec: Add/delete Security Association Database entry + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param entry - Entry to add or delete + */ +autoreply define ipsec_sad_entry_add_del +{ + u32 client_index; + u32 context; + u8 is_add; + vl_api_ipsec_sad_entry_t entry; }; /** \brief IPsec: Update Security Association keys @@ -173,10 +291,7 @@ autoreply define ipsec_sad_add_del_entry @param sa_id - sa id - @param crypto_key_length - length of crypto_key in bytes @param crypto_key - crypto keying material - - @param integrity_key_length - length of integrity_key in bytes @param integrity_key - integrity keying material */ @@ -187,11 +302,8 @@ autoreply define ipsec_sa_set_key u32 sa_id; - u8 crypto_key_length; - u8 crypto_key[128]; - - u8 integrity_key_length; - u8 integrity_key[128]; + vl_api_key_t crypto_key; + vl_api_key_t integrity_key; }; /** \brief IKEv2: Add/delete profile @@ -441,80 +553,6 @@ autoreply define ikev2_initiate_rekey_child_sa u32 ispi; }; -/** \brief Dump IPsec all SPD IDs - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ -define ipsec_spds_dump { - u32 client_index; - u32 context; -}; - -/** \brief Dump IPsec all SPD IDs response - @param client_index - opaque cookie to identify the sender - @param spd_id - SPD instance id (control plane allocated) - @param npolicies - number of policies in SPD -*/ -define ipsec_spds_details { - u32 context; - u32 spd_id; - u32 npolicies; -}; - -/** \brief Dump ipsec policy database data - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param spd_id - SPD instance id - @param sa_id - SA id, optional, set to ~0 to see all policies in SPD -*/ -define ipsec_spd_dump { - u32 client_index; - u32 context; - u32 spd_id; - u32 sa_id; -}; - -/** \brief IPsec policy database response - @param context - sender context which was passed in the request - @param spd_id - SPD instance id - @param priority - numeric value to control policy evaluation order - @param is_outbound - [1|0] to indicate if direction is [out|in]bound - @param is_ipv6 - [1|0] to indicate if address family is ipv[6|4] - @param local_start_addr - first address in local traffic selector range - @param local_stop_addr - last address in local traffic selector range - @param local_start_port - first port in local traffic selector range - @param local_stop_port - last port in local traffic selector range - @param remote_start_addr - first address in remote traffic selector range - @param remote_stop_addr - last address in remote traffic selector range - @param remote_start_port - first port in remote traffic selector range - @param remote_stop_port - last port in remote traffic selector range - @param protocol - traffic selector protocol - @param policy - policy action - @param sa_id - SA id - @param bytes - byte count of packets matching this policy - @param packets - count of packets matching this policy -*/ -define ipsec_spd_details { - u32 context; - u32 spd_id; - i32 priority; - u8 is_outbound; - u8 is_ipv6; - u8 local_start_addr[16]; - u8 local_stop_addr[16]; - u16 local_start_port; - u16 local_stop_port; - u8 remote_start_addr[16]; - u8 remote_stop_addr[16]; - u16 remote_start_port; - u16 remote_stop_port; - u8 protocol; - u8 policy; - u32 sa_id; - u64 bytes; - u64 packets; -}; - /** \brief IPsec: Get SPD interfaces @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -728,7 +766,7 @@ define ipsec_backend_dump { define ipsec_backend_details { u32 context; u8 name[128]; - u8 protocol; + vl_api_ipsec_proto_t protocol; u8 index; u8 active; }; @@ -742,7 +780,7 @@ define ipsec_backend_details { autoreply define ipsec_select_backend { u32 client_index; u32 context; - u8 protocol; + vl_api_ipsec_proto_t protocol; u8 index; }; diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h index 691bc071bba..93369fe9f8c 100644 --- a/src/vnet/ipsec/ipsec.h +++ b/src/vnet/ipsec/ipsec.h @@ -68,9 +68,11 @@ typedef enum #define _(v, f, s) IPSEC_POLICY_ACTION_##f = v, foreach_ipsec_policy_action #undef _ - IPSEC_POLICY_N_ACTION, } ipsec_policy_action_t; +#define IPSEC_POLICY_N_ACTION (IPSEC_POLICY_ACTION_PROTECT + 1) + + #define foreach_ipsec_crypto_alg \ _ (0, NONE, "none") \ _ (1, AES_CBC_128, "aes-cbc-128") \ @@ -220,7 +222,7 @@ typedef struct port_range_t rport; // Policy - u8 policy; + ipsec_policy_action_t policy; u32 sa_id; u32 sa_index; diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c index fc09f77db6c..eb78dbdd319 100644 --- a/src/vnet/ipsec/ipsec_api.c +++ b/src/vnet/ipsec/ipsec_api.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -51,8 +52,8 @@ #define foreach_vpe_api_msg \ _(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \ _(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \ -_(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \ -_(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \ +_(IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \ +_(IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \ _(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \ _(IPSEC_SA_DUMP, ipsec_sa_dump) \ _(IPSEC_SPDS_DUMP, ipsec_spds_dump) \ @@ -119,11 +120,29 @@ static void vl_api_ipsec_interface_add_del_spd_t_handler REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY); } -static void vl_api_ipsec_spd_add_del_entry_t_handler - (vl_api_ipsec_spd_add_del_entry_t * mp) +static int +ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in, + ipsec_policy_action_t * out) +{ + in = clib_net_to_host_u32 (in); + + switch (in) + { +#define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \ + *out = IPSEC_POLICY_ACTION_##f; \ + return (0); + foreach_ipsec_policy_action +#undef _ + } + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static void vl_api_ipsec_spd_entry_add_del_t_handler + (vl_api_ipsec_spd_entry_add_del_t * mp) { vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_spd_add_del_entry_reply_t *rmp; + vl_api_ipsec_spd_entry_add_del_reply_t *rmp; + ip46_type_t itype; int rv; #if WITH_LIBSSL > 0 @@ -131,45 +150,42 @@ static void vl_api_ipsec_spd_add_del_entry_t_handler clib_memset (&p, 0, sizeof (p)); - p.id = ntohl (mp->spd_id); - p.priority = ntohl (mp->priority); - p.is_outbound = mp->is_outbound; - p.is_ipv6 = mp->is_ipv6; + p.id = ntohl (mp->entry.spd_id); + p.priority = ntohl (mp->entry.priority); + p.is_outbound = mp->entry.is_outbound; + + itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start); + ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop); + ip_address_decode (&mp->entry.local_address_start, &p.laddr.start); + ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop); + + p.is_ipv6 = (itype == IP46_TYPE_IP6); + + p.protocol = mp->entry.protocol; + p.rport.start = ntohs (mp->entry.remote_port_start); + p.rport.stop = ntohs (mp->entry.remote_port_stop); + p.lport.start = ntohs (mp->entry.local_port_start); + p.lport.stop = ntohs (mp->entry.local_port_stop); + + rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy); + + if (rv) + goto out; - if (mp->is_ipv6 || mp->is_ip_any) - { - clib_memcpy (&p.raddr.start, mp->remote_address_start, 16); - clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16); - clib_memcpy (&p.laddr.start, mp->local_address_start, 16); - clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16); - } - else - { - clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4); - clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4); - clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4); - clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4); - } - p.protocol = mp->protocol; - p.rport.start = ntohs (mp->remote_port_start); - p.rport.stop = ntohs (mp->remote_port_stop); - p.lport.start = ntohs (mp->local_port_start); - p.lport.stop = ntohs (mp->local_port_stop); /* policy action resolve unsupported */ - if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE) + if (p.policy == IPSEC_POLICY_ACTION_RESOLVE) { clib_warning ("unsupported action: 'resolve'"); rv = VNET_API_ERROR_UNIMPLEMENTED; goto out; } - p.policy = mp->policy; - p.sa_id = ntohl (mp->sa_id); + p.sa_id = ntohl (mp->entry.sa_id); rv = ipsec_add_del_policy (vm, &p, mp->is_add); if (rv) goto out; - if (mp->is_ip_any) + if (mp->entry.is_ip_any) { p.is_ipv6 = 1; rv = ipsec_add_del_policy (vm, &p, mp->is_add); @@ -180,14 +196,89 @@ static void vl_api_ipsec_spd_add_del_entry_t_handler #endif out: - REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY); + REPLY_MACRO (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY); +} + +static int +ipsec_proto_decode (vl_api_ipsec_proto_t in, ipsec_protocol_t * out) +{ + in = clib_net_to_host_u32 (in); + + switch (in) + { + case IPSEC_API_PROTO_ESP: + *out = IPSEC_PROTOCOL_ESP; + return (0); + case IPSEC_API_PROTO_AH: + *out = IPSEC_PROTOCOL_AH; + return (0); + } + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static int +ipsec_crypto_algo_decode (vl_api_ipsec_crypto_alg_t in, + ipsec_crypto_alg_t * out) +{ + in = clib_net_to_host_u32 (in); + + switch (in) + { +#define _(v,f,s) case IPSEC_API_CRYPTO_ALG_##f: \ + *out = IPSEC_CRYPTO_ALG_##f; \ + return (0); + foreach_ipsec_crypto_alg +#undef _ + } + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static int +ipsec_integ_algo_decode (vl_api_ipsec_integ_alg_t in, ipsec_integ_alg_t * out) +{ + in = clib_net_to_host_u32 (in); + + switch (in) + { +#define _(v,f,s) case IPSEC_API_INTEG_ALG_##f: \ + *out = IPSEC_INTEG_ALG_##f; \ + return (0); + foreach_ipsec_integ_alg +#undef _ + } + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static void +vl_api_ipsec_key_decode (const vl_api_key_t * key, u8 * len, u8 out[128]) +{ + *len = key->length; + clib_memcpy (out, key->data, key->length); +} + +static void +vl_api_ipsec_sad_flags_decode (vl_api_ipsec_sad_flags_t in, ipsec_sa_t * sa) +{ + in = clib_net_to_host_u32 (in); + + if (in & IPSEC_API_SAD_FLAG_USE_EXTENDED_SEQ_NUM) + sa->use_esn = 1; + if (in & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY) + sa->use_anti_replay = 1; + if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL) + sa->is_tunnel = 1; + if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6) + sa->is_tunnel_ip6 = 1; + if (in & IPSEC_API_SAD_FLAG_UDP_ENCAP) + sa->udp_encap = 1; } -static void vl_api_ipsec_sad_add_del_entry_t_handler - (vl_api_ipsec_sad_add_del_entry_t * mp) + +static void vl_api_ipsec_sad_entry_add_del_t_handler + (vl_api_ipsec_sad_entry_add_del_t * mp) { vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_sad_add_del_entry_reply_t *rmp; + vl_api_ipsec_sad_entry_add_del_reply_t *rmp; int rv; #if WITH_LIBSSL > 0 ipsec_main_t *im = &ipsec_main; @@ -195,47 +286,36 @@ static void vl_api_ipsec_sad_add_del_entry_t_handler clib_memset (&sa, 0, sizeof (sa)); - sa.id = ntohl (mp->sad_id); - sa.spi = ntohl (mp->spi); - sa.protocol = mp->protocol; - /* check for unsupported crypto-alg */ - if (mp->crypto_algorithm >= IPSEC_CRYPTO_N_ALG) - { - clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg, - mp->crypto_algorithm); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - sa.crypto_alg = mp->crypto_algorithm; - sa.crypto_key_len = mp->crypto_key_length; - clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); - /* check for unsupported integ-alg */ - if (mp->integrity_algorithm >= IPSEC_INTEG_N_ALG) - { - clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg, - mp->integrity_algorithm); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } + sa.id = ntohl (mp->entry.sad_id); + sa.spi = ntohl (mp->entry.spi); - sa.integ_alg = mp->integrity_algorithm; - sa.integ_key_len = mp->integrity_key_length; - clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); - sa.use_esn = mp->use_extended_sequence_number; - sa.is_tunnel = mp->is_tunnel; - sa.is_tunnel_ip6 = mp->is_tunnel_ipv6; - sa.udp_encap = mp->udp_encap; - if (sa.is_tunnel_ip6) - { - clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16); - clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16); - } - else + rv = ipsec_proto_decode (mp->entry.protocol, &sa.protocol); + + if (rv) + goto out; + + rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &sa.crypto_alg); + + if (rv) + goto out; + + rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &sa.integ_alg); + + if (rv) + goto out; + + vl_api_ipsec_key_decode (&mp->entry.crypto_key, + &sa.crypto_key_len, sa.crypto_key); + vl_api_ipsec_key_decode (&mp->entry.integrity_key, + &sa.integ_key_len, sa.integ_key); + + vl_api_ipsec_sad_flags_decode (mp->entry.flags, &sa); + + if (sa.is_tunnel_ip6 || sa.is_tunnel) { - clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4); - clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4); + ip_address_decode (&mp->entry.tunnel_src, &sa.tunnel_src_addr); + ip_address_decode (&mp->entry.tunnel_dst, &sa.tunnel_dst_addr); } - sa.use_anti_replay = mp->use_anti_replay; clib_error_t *err = ipsec_check_support_cb (im, &sa); if (err) @@ -252,7 +332,7 @@ static void vl_api_ipsec_sad_add_del_entry_t_handler #endif out: - REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY); + REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY); } static void @@ -293,6 +373,22 @@ vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp) #endif } +vl_api_ipsec_spd_action_t +ipsec_spd_action_encode (ipsec_policy_action_t in) +{ + vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS; + + switch (in) + { +#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \ + out = IPSEC_API_SPD_ACTION_##f; \ + break; + foreach_ipsec_policy_action +#undef _ + } + return (clib_host_to_net_u32 (out)); +} + static void send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg, u32 context) @@ -304,31 +400,26 @@ send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg, mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS); mp->context = context; - mp->spd_id = htonl (p->id); - mp->priority = htonl (p->priority); - mp->is_outbound = p->is_outbound; - mp->is_ipv6 = p->is_ipv6; - if (p->is_ipv6) - { - memcpy (mp->local_start_addr, &p->laddr.start.ip6, 16); - memcpy (mp->local_stop_addr, &p->laddr.stop.ip6, 16); - memcpy (mp->remote_start_addr, &p->raddr.start.ip6, 16); - memcpy (mp->remote_stop_addr, &p->raddr.stop.ip6, 16); - } - else - { - memcpy (mp->local_start_addr, &p->laddr.start.ip4, 4); - memcpy (mp->local_stop_addr, &p->laddr.stop.ip4, 4); - memcpy (mp->remote_start_addr, &p->raddr.start.ip4, 4); - memcpy (mp->remote_stop_addr, &p->raddr.stop.ip4, 4); - } - mp->local_start_port = htons (p->lport.start); - mp->local_stop_port = htons (p->lport.stop); - mp->remote_start_port = htons (p->rport.start); - mp->remote_stop_port = htons (p->rport.stop); - mp->protocol = p->protocol; - mp->policy = p->policy; - mp->sa_id = htonl (p->sa_id); + mp->entry.spd_id = htonl (p->id); + mp->entry.priority = htonl (p->priority); + mp->entry.is_outbound = p->is_outbound; + + ip_address_encode (&p->laddr.start, IP46_TYPE_ANY, + &mp->entry.local_address_start); + ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY, + &mp->entry.local_address_stop); + ip_address_encode (&p->raddr.start, IP46_TYPE_ANY, + &mp->entry.remote_address_start); + ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY, + &mp->entry.remote_address_stop); + mp->entry.local_port_start = htons (p->lport.start); + mp->entry.local_port_stop = htons (p->lport.stop); + mp->entry.remote_port_start = htons (p->rport.start); + mp->entry.remote_port_stop = htons (p->rport.stop); + mp->entry.protocol = p->protocol; + mp->entry.policy = ipsec_spd_action_encode (p->policy); + mp->entry.sa_id = htonl (p->sa_id); + mp->bytes = clib_host_to_net_u64 (p->counter.bytes); mp->packets = clib_host_to_net_u64 (p->counter.packets); @@ -432,10 +523,11 @@ vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp) #if WITH_LIBSSL > 0 ipsec_sa_t sa; sa.id = ntohl (mp->sa_id); - sa.crypto_key_len = mp->crypto_key_length; - clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); - sa.integ_key_len = mp->integrity_key_length; - clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); + + vl_api_ipsec_key_decode (&mp->crypto_key, + &sa.crypto_key_len, sa.crypto_key); + vl_api_ipsec_key_decode (&mp->integrity_key, + &sa.integ_key_len, sa.integ_key); rv = ipsec_set_sa_key (vm, &sa); #else @@ -1033,7 +1125,7 @@ vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp) mp->context = context; snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name), ab->name); - mp->protocol = IPSEC_PROTOCOL_AH; + mp->protocol = ntohl (IPSEC_API_PROTO_AH); mp->index = ab - im->ah_backends; mp->active = mp->index == im->ah_current_backend ? 1 : 0; vl_api_send_msg (rp, (u8 *)mp); @@ -1045,7 +1137,7 @@ vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp) mp->context = context; snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name), eb->name); - mp->protocol = IPSEC_PROTOCOL_ESP; + mp->protocol = ntohl (IPSEC_API_PROTO_ESP); mp->index = eb - im->esp_backends; mp->active = mp->index == im->esp_current_backend ? 1 : 0; vl_api_send_msg (rp, (u8 *)mp); @@ -1058,14 +1150,21 @@ vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp) { ipsec_main_t *im = &ipsec_main; vl_api_ipsec_select_backend_reply_t *rmp; + ipsec_protocol_t protocol; int rv = 0; if (pool_elts (im->sad) > 0) { rv = VNET_API_ERROR_INSTANCE_IN_USE; goto done; } + + rv = ipsec_proto_decode (mp->protocol, &protocol); + + if (rv) + goto done; + #if WITH_LIBSSL > 0 - switch (mp->protocol) + switch (protocol) { case IPSEC_PROTOCOL_ESP: if (pool_is_free_index (im->esp_backends, mp->index)) diff --git a/test/template_ipsec.py b/test/template_ipsec.py index ed7c1a32129..7888a6788ab 100644 --- a/test/template_ipsec.py +++ b/test/template_ipsec.py @@ -8,60 +8,71 @@ from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest from framework import VppTestCase, VppTestRunner from util import ppp +from vpp_papi import VppEnum class IPsecIPv4Params(object): + addr_type = socket.AF_INET addr_any = "0.0.0.0" addr_bcast = "255.255.255.255" addr_len = 32 is_ipv6 = 0 - remote_tun_if_host = '1.1.1.1' - scapy_tun_sa_id = 10 - scapy_tun_spi = 1001 - vpp_tun_sa_id = 20 - vpp_tun_spi = 1000 + def __init__(self): + self.remote_tun_if_host = '1.1.1.1' + + self.scapy_tun_sa_id = 10 + self.scapy_tun_spi = 1001 + self.vpp_tun_sa_id = 20 + self.vpp_tun_spi = 1000 - scapy_tra_sa_id = 30 - scapy_tra_spi = 2001 - vpp_tra_sa_id = 40 - vpp_tra_spi = 2000 + self.scapy_tra_sa_id = 30 + self.scapy_tra_spi = 2001 + self.vpp_tra_sa_id = 40 + self.vpp_tra_spi = 2000 - auth_algo_vpp_id = 2 # internal VPP enum value for SHA1_96 - auth_algo = 'HMAC-SHA1-96' # scapy name - auth_key = 'C91KUR9GYMm5GfkEvNjX' + self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t. + IPSEC_API_INTEG_ALG_SHA1_96) + self.auth_algo = 'HMAC-SHA1-96' # scapy name + self.auth_key = 'C91KUR9GYMm5GfkEvNjX' - crypt_algo_vpp_id = 1 # internal VPP enum value for AES_CBC_128 - crypt_algo = 'AES-CBC' # scapy name - crypt_key = 'JPjyOWBeVEQiMe7h' + self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t. + IPSEC_API_CRYPTO_ALG_AES_CBC_128) + self.crypt_algo = 'AES-CBC' # scapy name + self.crypt_key = 'JPjyOWBeVEQiMe7h' class IPsecIPv6Params(object): + addr_type = socket.AF_INET6 addr_any = "0::0" addr_bcast = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" addr_len = 128 is_ipv6 = 1 - remote_tun_if_host = '1111:1111:1111:1111:1111:1111:1111:1111' - scapy_tun_sa_id = 50 - scapy_tun_spi = 3001 - vpp_tun_sa_id = 60 - vpp_tun_spi = 3000 + def __init__(self): + self.remote_tun_if_host = '1111:1111:1111:1111:1111:1111:1111:1111' + + self.scapy_tun_sa_id = 50 + self.scapy_tun_spi = 3001 + self.vpp_tun_sa_id = 60 + self.vpp_tun_spi = 3000 - scapy_tra_sa_id = 70 - scapy_tra_spi = 4001 - vpp_tra_sa_id = 80 - vpp_tra_spi = 4000 + self.scapy_tra_sa_id = 70 + self.scapy_tra_spi = 4001 + self.vpp_tra_sa_id = 80 + self.vpp_tra_spi = 4000 - auth_algo_vpp_id = 4 # internal VPP enum value for SHA_256_128 - auth_algo = 'SHA2-256-128' # scapy name - auth_key = 'C91KUR9GYMm5GfkEvNjX' + self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t. + IPSEC_API_INTEG_ALG_SHA_256_128) + self.auth_algo = 'SHA2-256-128' # scapy name + self.auth_key = 'C91KUR9GYMm5GfkEvNjX' - crypt_algo_vpp_id = 3 # internal VPP enum value for AES_CBC_256 - crypt_algo = 'AES-CBC' # scapy name - crypt_key = 'JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h' + self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t. + IPSEC_API_CRYPTO_ALG_AES_CBC_256) + self.crypt_algo = 'AES-CBC' # scapy name + self.crypt_key = 'JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h' class TemplateIpsec(VppTestCase): @@ -101,8 +112,10 @@ class TemplateIpsec(VppTestCase): self.tun_spd_id = 1 self.tra_spd_id = 2 - self.vpp_esp_protocol = 1 - self.vpp_ah_protocol = 0 + self.vpp_esp_protocol = (VppEnum.vl_api_ipsec_proto_t. + IPSEC_API_PROTO_ESP) + self.vpp_ah_protocol = (VppEnum.vl_api_ipsec_proto_t. + IPSEC_API_PROTO_AH) self.create_pg_interfaces(range(3)) self.interfaces = list(self.pg_interfaces) diff --git a/test/test_ipsec_ah.py b/test/test_ipsec_ah.py index 63e368c0a4a..caec8d431c5 100644 --- a/test/test_ipsec_ah.py +++ b/test/test_ipsec_ah.py @@ -10,6 +10,7 @@ from vpp_ipsec import VppIpsecSA, VppIpsecSpd, VppIpsecSpdEntry,\ VppIpsecSpdItfBinding from vpp_ip_route import VppIpRoute, VppRoutePath from vpp_ip import DpoProto +from vpp_papi import VppEnum class TemplateIpsecAh(TemplateIpsec): @@ -83,6 +84,8 @@ class TemplateIpsecAh(TemplateIpsec): remote_tun_if_host = params.remote_tun_if_host addr_any = params.addr_any addr_bcast = params.addr_bcast + e = VppEnum.vl_api_ipsec_spd_action_t + VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, @@ -111,28 +114,32 @@ class TemplateIpsecAh(TemplateIpsec): remote_tun_if_host, self.pg1.remote_addr[addr_type], self.pg1.remote_addr[addr_type], - 0, priority=10, policy=3, + 0, priority=10, + policy=e.IPSEC_API_SPD_ACTION_PROTECT, is_outbound=0).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id, self.pg1.remote_addr[addr_type], self.pg1.remote_addr[addr_type], remote_tun_if_host, remote_tun_if_host, - 0, priority=10, policy=3).add_vpp_config() + 0, policy=e.IPSEC_API_SPD_ACTION_PROTECT, + priority=10).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, vpp_tun_sa_id, remote_tun_if_host, remote_tun_if_host, self.pg0.local_addr[addr_type], self.pg0.local_addr[addr_type], - 0, priority=20, policy=3, + 0, priority=20, + policy=e.IPSEC_API_SPD_ACTION_PROTECT, is_outbound=0).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id, self.pg0.local_addr[addr_type], self.pg0.local_addr[addr_type], remote_tun_if_host, remote_tun_if_host, - 0, priority=20, policy=3).add_vpp_config() + 0, policy=e.IPSEC_API_SPD_ACTION_PROTECT, + priority=20).add_vpp_config() def config_ah_tra(self, params): addr_type = params.addr_type @@ -146,17 +153,20 @@ class TemplateIpsecAh(TemplateIpsec): crypt_key = params.crypt_key addr_any = params.addr_any addr_bcast = params.addr_bcast + flags = (VppEnum.vl_api_ipsec_sad_flags_t. + IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY) + e = VppEnum.vl_api_ipsec_spd_action_t VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, self.vpp_ah_protocol, - use_anti_replay=1).add_vpp_config() + flags=flags).add_vpp_config() VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, self.vpp_ah_protocol, - use_anti_replay=1).add_vpp_config() + flags=flags).add_vpp_config() VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id, addr_any, addr_bcast, @@ -173,14 +183,16 @@ class TemplateIpsecAh(TemplateIpsec): self.tra_if.local_addr[addr_type], self.tra_if.remote_addr[addr_type], self.tra_if.remote_addr[addr_type], - 0, priority=10, policy=3, + 0, priority=10, + policy=e.IPSEC_API_SPD_ACTION_PROTECT, is_outbound=0).add_vpp_config() VppIpsecSpdEntry(self, self.tra_spd, scapy_tra_sa_id, self.tra_if.local_addr[addr_type], self.tra_if.local_addr[addr_type], self.tra_if.remote_addr[addr_type], self.tra_if.remote_addr[addr_type], - 0, priority=10, policy=3).add_vpp_config() + 0, policy=e.IPSEC_API_SPD_ACTION_PROTECT, + priority=10).add_vpp_config() class TestIpsecAh1(TemplateIpsecAh, IpsecTraTests, IpsecTunTests): diff --git a/test/test_ipsec_api.py b/test/test_ipsec_api.py index 30496b3792f..8aea42ab3df 100644 --- a/test/test_ipsec_api.py +++ b/test/test_ipsec_api.py @@ -1,7 +1,8 @@ import unittest from framework import VppTestCase, VppTestRunner -from template_ipsec import IPsecIPv4Params +from template_ipsec import TemplateIpsec, IPsecIPv4Params +from vpp_papi import VppEnum class IpsecApiTestCase(VppTestCase): @@ -13,8 +14,10 @@ class IpsecApiTestCase(VppTestCase): self.pg0.config_ip4() self.pg0.admin_up() - self.vpp_esp_protocol = 1 - self.vpp_ah_protocol = 0 + self.vpp_esp_protocol = (VppEnum.vl_api_ipsec_proto_t. + IPSEC_API_PROTO_ESP) + self.vpp_ah_protocol = (VppEnum.vl_api_ipsec_proto_t. + IPSEC_API_PROTO_AH) self.ipv4_params = IPsecIPv4Params() def tearDown(self): @@ -59,24 +62,22 @@ class IpsecApiTestCase(VppTestCase): crypt_algo_vpp_id = params.crypt_algo_vpp_id crypt_key = params.crypt_key - self.vapi.ipsec_sad_add_del_entry(scapy_tun_sa_id, scapy_tun_spi, + self.vapi.ipsec_sad_entry_add_del(scapy_tun_sa_id, scapy_tun_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, self.vpp_ah_protocol, - self.pg0.local_addr_n[addr_type], - self.pg0.remote_addr_n[addr_type], - is_tunnel=1, is_tunnel_ipv6=is_ipv6) + self.pg0.local_addr[addr_type], + self.pg0.remote_addr[addr_type]) with self.vapi.assert_negative_api_retval(): self.vapi.ipsec_select_backend( protocol=self.vpp_ah_protocol, index=0) - self.vapi.ipsec_sad_add_del_entry(scapy_tun_sa_id, scapy_tun_spi, + self.vapi.ipsec_sad_entry_add_del(scapy_tun_sa_id, scapy_tun_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, self.vpp_ah_protocol, - self.pg0.local_addr_n[addr_type], - self.pg0.remote_addr_n[addr_type], - is_tunnel=1, is_tunnel_ipv6=is_ipv6, + self.pg0.local_addr[addr_type], + self.pg0.remote_addr[addr_type], is_add=0) self.vapi.ipsec_select_backend( protocol=self.vpp_ah_protocol, index=0) diff --git a/test/test_ipsec_esp.py b/test/test_ipsec_esp.py index 96e4833621a..ae62aecc2ed 100644 --- a/test/test_ipsec_esp.py +++ b/test/test_ipsec_esp.py @@ -9,6 +9,7 @@ from vpp_ipsec import VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSA,\ VppIpsecSpdItfBinding from vpp_ip_route import VppIpRoute, VppRoutePath from vpp_ip import DpoProto +from vpp_papi import VppEnum class TemplateIpsecEsp(TemplateIpsec): @@ -94,6 +95,7 @@ class TemplateIpsecEsp(TemplateIpsec): remote_tun_if_host = params.remote_tun_if_host addr_any = params.addr_any addr_bcast = params.addr_bcast + e = VppEnum.vl_api_ipsec_spd_action_t VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi, auth_algo_vpp_id, auth_key, @@ -123,28 +125,32 @@ class TemplateIpsecEsp(TemplateIpsec): self.pg1.remote_addr[addr_type], self.pg1.remote_addr[addr_type], 0, - priority=10, policy=3, + priority=10, + policy=e.IPSEC_API_SPD_ACTION_PROTECT, is_outbound=0).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id, self.pg1.remote_addr[addr_type], self.pg1.remote_addr[addr_type], remote_tun_if_host, remote_tun_if_host, 0, - priority=10, policy=3).add_vpp_config() + policy=e.IPSEC_API_SPD_ACTION_PROTECT, + priority=10).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, vpp_tun_sa_id, remote_tun_if_host, remote_tun_if_host, self.pg0.local_addr[addr_type], self.pg0.local_addr[addr_type], 0, - priority=20, policy=3, + priority=20, + policy=e.IPSEC_API_SPD_ACTION_PROTECT, is_outbound=0).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id, self.pg0.local_addr[addr_type], self.pg0.local_addr[addr_type], remote_tun_if_host, remote_tun_if_host, 0, - priority=20, policy=3).add_vpp_config() + policy=e.IPSEC_API_SPD_ACTION_PROTECT, + priority=20).add_vpp_config() def config_esp_tra(self, params): addr_type = params.addr_type @@ -158,17 +164,20 @@ class TemplateIpsecEsp(TemplateIpsec): crypt_key = params.crypt_key addr_any = params.addr_any addr_bcast = params.addr_bcast + flags = (VppEnum.vl_api_ipsec_sad_flags_t. + IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY) + e = VppEnum.vl_api_ipsec_spd_action_t VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, self.vpp_esp_protocol, - use_anti_replay=1).add_vpp_config() + flags=flags).add_vpp_config() VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, self.vpp_esp_protocol, - use_anti_replay=1).add_vpp_config() + flags=flags).add_vpp_config() VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id, addr_any, addr_bcast, @@ -185,14 +194,16 @@ class TemplateIpsecEsp(TemplateIpsec): self.tra_if.local_addr[addr_type], self.tra_if.remote_addr[addr_type], self.tra_if.remote_addr[addr_type], - 0, priority=10, policy=3, + 0, priority=10, + policy=e.IPSEC_API_SPD_ACTION_PROTECT, is_outbound=0).add_vpp_config() VppIpsecSpdEntry(self, self.tra_spd, scapy_tra_sa_id, self.tra_if.local_addr[addr_type], self.tra_if.local_addr[addr_type], self.tra_if.remote_addr[addr_type], self.tra_if.remote_addr[addr_type], - 0, priority=10, policy=3).add_vpp_config() + 0, policy=e.IPSEC_API_SPD_ACTION_PROTECT, + priority=10).add_vpp_config() class TestIpsecEsp1(TemplateIpsecEsp, IpsecTraTests, IpsecTunTests): diff --git a/test/test_ipsec_nat.py b/test/test_ipsec_nat.py index 89418b108e2..cdb9cb438f2 100644 --- a/test/test_ipsec_nat.py +++ b/test/test_ipsec_nat.py @@ -11,6 +11,7 @@ from vpp_ipsec import VppIpsecSA, VppIpsecSpd, VppIpsecSpdEntry,\ VppIpsecSpdItfBinding from vpp_ip_route import VppIpRoute, VppRoutePath from vpp_ip import DpoProto +from vpp_papi import VppEnum class IPSecNATTestCase(TemplateIpsec): @@ -155,6 +156,9 @@ class IPSecNATTestCase(TemplateIpsec): crypt_key = params.crypt_key addr_any = params.addr_any addr_bcast = params.addr_bcast + flags = (VppEnum.vl_api_ipsec_sad_flags_t. + IPSEC_API_SAD_FLAG_UDP_ENCAP) + e = VppEnum.vl_api_ipsec_spd_action_t VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi, auth_algo_vpp_id, auth_key, @@ -162,14 +166,14 @@ class IPSecNATTestCase(TemplateIpsec): self.vpp_esp_protocol, self.pg1.remote_addr[addr_type], self.tun_if.remote_addr[addr_type], - udp_encap=1).add_vpp_config() + flags=flags).add_vpp_config() VppIpsecSA(self, vpp_tun_sa_id, vpp_tun_spi, auth_algo_vpp_id, auth_key, crypt_algo_vpp_id, crypt_key, self.vpp_esp_protocol, self.tun_if.remote_addr[addr_type], self.pg1.remote_addr[addr_type], - udp_encap=1).add_vpp_config() + flags=flags).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id, addr_any, addr_bcast, @@ -198,14 +202,16 @@ class IPSecNATTestCase(TemplateIpsec): self.tun_if.remote_addr[addr_type], self.pg1.remote_addr[addr_type], self.pg1.remote_addr[addr_type], - 0, priority=10, policy=3, + 0, priority=10, + policy=e.IPSEC_API_SPD_ACTION_PROTECT, is_outbound=0).add_vpp_config() VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id, self.pg1.remote_addr[addr_type], self.pg1.remote_addr[addr_type], self.tun_if.remote_addr[addr_type], self.tun_if.remote_addr[addr_type], - 0, priority=10, policy=3).add_vpp_config() + 0, policy=e.IPSEC_API_SPD_ACTION_PROTECT, + priority=10).add_vpp_config() def test_ipsec_nat_tun(self): """ IPSec/NAT tunnel test case """ diff --git a/test/vpp_ipsec.py b/test/vpp_ipsec.py index 8c6da77cba8..1218c4bb8bb 100644 --- a/test/vpp_ipsec.py +++ b/test/vpp_ipsec.py @@ -1,5 +1,6 @@ from vpp_object import * from ipaddress import ip_address +from vpp_papi import VppEnum try: text_type = unicode @@ -82,7 +83,7 @@ class VppIpsecSpdEntry(VppObject): remote_start, remote_stop, proto, priority=100, - policy=0, + policy=None, is_outbound=1, remote_port_start=0, remote_port_stop=65535, @@ -98,7 +99,11 @@ class VppIpsecSpdEntry(VppObject): self.proto = proto self.is_outbound = is_outbound self.priority = priority - self.policy = policy + if not policy: + self.policy = (VppEnum.vl_api_ipsec_spd_action_t. + IPSEC_API_SPD_ACTION_BYPASS) + else: + self.policy = policy self.is_ipv6 = (0 if self.local_start.version == 4 else 1) self.local_port_start = local_port_start self.local_port_stop = local_port_stop @@ -106,13 +111,13 @@ class VppIpsecSpdEntry(VppObject): self.remote_port_stop = remote_port_stop def add_vpp_config(self): - self.test.vapi.ipsec_spd_add_del_entry( + self.test.vapi.ipsec_spd_entry_add_del( self.spd.id, self.sa_id, - self.local_start.packed, - self.local_stop.packed, - self.remote_start.packed, - self.remote_stop.packed, + self.local_start, + self.local_stop, + self.remote_start, + self.remote_stop, protocol=self.proto, is_ipv6=self.is_ipv6, is_outbound=self.is_outbound, @@ -125,13 +130,13 @@ class VppIpsecSpdEntry(VppObject): self.test.registry.register(self, self.test.logger) def remove_vpp_config(self): - self.test.vapi.ipsec_spd_add_del_entry( + self.test.vapi.ipsec_spd_entry_add_del( self.spd.id, self.sa_id, - self.local_start.packed, - self.local_stop.packed, - self.remote_start.packed, - self.remote_stop.packed, + self.local_start, + self.local_stop, + self.remote_start, + self.remote_stop, protocol=self.proto, is_ipv6=self.is_ipv6, is_outbound=self.is_outbound, @@ -157,12 +162,12 @@ class VppIpsecSpdEntry(VppObject): def query_vpp_config(self): ss = self.test.vapi.ipsec_spd_dump(self.spd.id) for s in ss: - if s.sa_id == self.sa_id and \ - s.is_outbound == self.is_outbound and \ - s.priority == self.priority and \ - s.policy == self.policy and \ - s.is_ipv6 == self.is_ipv6 and \ - s.remote_start_port == self.remote_port_start: + if s.entry.sa_id == self.sa_id and \ + s.entry.is_outbound == self.is_outbound and \ + s.entry.priority == self.priority and \ + s.entry.policy == self.policy and \ + s.entry.remote_address_start == self.remote_start and \ + s.entry.remote_port_start == self.remote_port_start: return True return False @@ -177,8 +182,8 @@ class VppIpsecSA(VppObject): crypto_alg, crypto_key, proto, tun_src=None, tun_dst=None, - use_anti_replay=0, - udp_encap=0): + flags=None): + e = VppEnum.vl_api_ipsec_sad_flags_t self.test = test self.id = id self.spi = spi @@ -187,22 +192,23 @@ class VppIpsecSA(VppObject): self.crypto_alg = crypto_alg self.crypto_key = crypto_key self.proto = proto - self.is_tunnel = 0 - self.is_tunnel_v6 = 0 + self.tun_src = tun_src self.tun_dst = tun_dst + if not flags: + self.flags = e.IPSEC_API_SAD_FLAG_NONE + else: + self.flags = flags if (tun_src): self.tun_src = ip_address(text_type(tun_src)) - self.is_tunnel = 1 + self.flags = self.flags | e.IPSEC_API_SAD_FLAG_IS_TUNNEL if (self.tun_src.version == 6): - self.is_tunnel_v6 = 1 + self.flags = self.flags | e.IPSEC_API_SAD_FLAG_IS_TUNNEL_V6 if (tun_dst): self.tun_dst = ip_address(text_type(tun_dst)) - self.use_anti_replay = use_anti_replay - self.udp_encap = udp_encap def add_vpp_config(self): - self.test.vapi.ipsec_sad_add_del_entry( + self.test.vapi.ipsec_sad_entry_add_del( self.id, self.spi, self.integ_alg, @@ -210,16 +216,13 @@ class VppIpsecSA(VppObject): self.crypto_alg, self.crypto_key, self.proto, - (self.tun_src.packed if self.tun_src else []), - (self.tun_dst.packed if self.tun_dst else []), - is_tunnel=self.is_tunnel, - is_tunnel_ipv6=self.is_tunnel_v6, - use_anti_replay=self.use_anti_replay, - udp_encap=self.udp_encap) + (self.tun_src if self.tun_src else []), + (self.tun_dst if self.tun_dst else []), + flags=self.flags) self.test.registry.register(self, self.test.logger) def remove_vpp_config(self): - self.test.vapi.ipsec_sad_add_del_entry( + self.test.vapi.ipsec_sad_entry_add_del( self.id, self.spi, self.integ_alg, @@ -227,12 +230,9 @@ class VppIpsecSA(VppObject): self.crypto_alg, self.crypto_key, self.proto, - (self.tun_src.packed if self.tun_src else []), - (self.tun_dst.packed if self.tun_dst else []), - is_tunnel=self.is_tunnel, - is_tunnel_ipv6=self.is_tunnel_v6, - use_anti_replay=self.use_anti_replay, - udp_encap=self.udp_encap, + (self.tun_src if self.tun_src else []), + (self.tun_dst if self.tun_dst else []), + flags=self.flags, is_add=0) def __str__(self): diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index efe1454c934..d22cc7c4b49 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -3369,7 +3369,7 @@ class VppPapiProvider(object): {'spd_index': spd_index if spd_index else 0, 'spd_index_valid': 1 if spd_index else 0}) - def ipsec_sad_add_del_entry(self, + def ipsec_sad_entry_add_del(self, sad_id, spi, integrity_algorithm, @@ -3379,12 +3379,8 @@ class VppPapiProvider(object): protocol, tunnel_src_address='', tunnel_dst_address='', - is_tunnel=1, - is_tunnel_ipv6=0, - is_add=1, - udp_encap=0, - use_anti_replay=0, - use_extended_sequence_number=0): + flags=0, + is_add=1): """ IPSEC SA add/del :param sad_id: security association ID :param spi: security param index of the SA in decimal @@ -3401,31 +3397,35 @@ class VppPapiProvider(object): crypto and ipsec algorithms """ return self.api( - self.papi.ipsec_sad_add_del_entry, - {'sad_id': sad_id, - 'spi': spi, - 'tunnel_src_address': tunnel_src_address, - 'tunnel_dst_address': tunnel_dst_address, - 'protocol': protocol, - 'integrity_algorithm': integrity_algorithm, - 'integrity_key_length': len(integrity_key), - 'integrity_key': integrity_key, - 'crypto_algorithm': crypto_algorithm, - 'crypto_key_length': len(crypto_key) if crypto_key is not None - else 0, - 'crypto_key': crypto_key, - 'is_add': is_add, - 'is_tunnel': is_tunnel, - 'is_tunnel_ipv6': is_tunnel_ipv6, - 'udp_encap': udp_encap, - 'use_extended_sequence_number': use_extended_sequence_number, - 'use_anti_replay': use_anti_replay}) + self.papi.ipsec_sad_entry_add_del, + { + 'is_add': is_add, + 'entry': + { + 'sad_id': sad_id, + 'spi': spi, + 'tunnel_src': tunnel_src_address, + 'tunnel_dst': tunnel_dst_address, + 'protocol': protocol, + 'integrity_algorithm': integrity_algorithm, + 'integrity_key': { + 'length': len(integrity_key), + 'data': integrity_key, + }, + 'crypto_algorithm': crypto_algorithm, + 'crypto_key': { + 'length': len(crypto_key), + 'data': crypto_key, + }, + 'flags': flags, + } + }) def ipsec_sa_dump(self, sa_id=None): return self.api(self.papi.ipsec_sa_dump, {'sa_id': sa_id if sa_id else 0xffffffff}) - def ipsec_spd_add_del_entry(self, + def ipsec_spd_entry_add_del(self, spd_id, sa_id, local_address_start, @@ -3464,24 +3464,28 @@ class VppPapiProvider(object): :param is_add: (Default value = 1) """ return self.api( - self.papi.ipsec_spd_add_del_entry, - {'spd_id': spd_id, - 'sa_id': sa_id, - 'local_address_start': local_address_start, - 'local_address_stop': local_address_stop, - 'remote_address_start': remote_address_start, - 'remote_address_stop': remote_address_stop, - 'local_port_start': local_port_start, - 'local_port_stop': local_port_stop, - 'remote_port_start': remote_port_start, - 'remote_port_stop': remote_port_stop, - 'is_add': is_add, - 'protocol': protocol, - 'policy': policy, - 'priority': priority, - 'is_outbound': is_outbound, - 'is_ipv6': is_ipv6, - 'is_ip_any': is_ip_any}) + self.papi.ipsec_spd_entry_add_del, + { + 'is_add': is_add, + 'entry': + { + 'spd_id': spd_id, + 'sa_id': sa_id, + 'local_address_start': local_address_start, + 'local_address_stop': local_address_stop, + 'remote_address_start': remote_address_start, + 'remote_address_stop': remote_address_stop, + 'local_port_start': local_port_start, + 'local_port_stop': local_port_stop, + 'remote_port_start': remote_port_start, + 'remote_port_stop': remote_port_stop, + 'protocol': protocol, + 'policy': policy, + 'priority': priority, + 'is_outbound': is_outbound, + 'is_ip_any': is_ip_any + } + }) def ipsec_spd_dump(self, spd_id, sa_id=0xffffffff): return self.api(self.papi.ipsec_spd_dump, -- 2.16.6