ipsec: remove dedicated IPSec tunnels

APIs for dedicated IPSec tunnels will remain in this release and are
used to programme the IPIP tunnel protect. APIs will be removed in a
future release.

see:
 https://wiki.fd.io/view/VPP/IPSec

Type: feature

Change-Id: I0f01f597946fdd15dfa5cae3643104d5a9c83089
Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
Neale Ranns
2019-09-26 16:20:19 +00:00
committed by Damjan Marion
parent f1653e62fe
commit 12989b5388
25 changed files with 622 additions and 1733 deletions

View File

@ -570,8 +570,6 @@ list(APPEND VNET_SOURCES
ipsec/ipsec_cli.c
ipsec/ipsec_format.c
ipsec/ipsec_input.c
ipsec/ipsec_if.c
ipsec/ipsec_if_in.c
ipsec/ipsec_punt.c
ipsec/ipsec_sa.c
ipsec/ipsec_spd.c
@ -591,7 +589,6 @@ list(APPEND VNET_MULTIARCH_SOURCES
ipsec/esp_decrypt.c
ipsec/ah_decrypt.c
ipsec/ah_encrypt.c
ipsec/ipsec_if_in.c
ipsec/ipsec_output.c
ipsec/ipsec_input.c
ipsec/ipsec_tun_in.c
@ -608,7 +605,7 @@ list(APPEND VNET_HEADERS
ipsec/ipsec_spd.h
ipsec/ipsec_spd_policy.h
ipsec/ipsec_sa.h
ipsec/ipsec_if.h
ipsec/ipsec_tun.h
ipsec/ipsec_punt.h
ipsec/esp.h
ipsec/ah.h

View File

@ -47,7 +47,8 @@ typedef enum
_(RUNT, "undersized packet") \
_(CHAINED_BUFFER, "chained buffers (packet dropped)") \
_(OVERSIZED_HEADER, "buffer with oversized header (dropped)") \
_(NO_TAIL_SPACE, "no enough buffer tail space (dropped)")
_(NO_TAIL_SPACE, "no enough buffer tail space (dropped)") \
_(TUN_NO_PROTO, "no tunnel protocol") \
typedef enum
@ -497,8 +498,11 @@ esp_decrypt_inline (vlib_main_t * vm,
&ip4->dst_address) ||
!ip46_address_is_equal_v4 (&itp->itp_tun.dst,
&ip4->src_address))
next[0] = ESP_DECRYPT_NEXT_DROP;
{
next[0] = ESP_DECRYPT_NEXT_DROP;
b[0]->error =
node->errors[ESP_DECRYPT_ERROR_TUN_NO_PROTO];
}
}
else if (f->next_header == IP_PROTOCOL_IPV6)
{
@ -510,7 +514,11 @@ esp_decrypt_inline (vlib_main_t * vm,
&ip6->dst_address) ||
!ip46_address_is_equal_v6 (&itp->itp_tun.dst,
&ip6->src_address))
next[0] = ESP_DECRYPT_NEXT_DROP;
{
next[0] = ESP_DECRYPT_NEXT_DROP;
b[0]->error =
node->errors[ESP_DECRYPT_ERROR_TUN_NO_PROTO];
}
}
}
}
@ -615,16 +623,9 @@ VLIB_REGISTER_NODE (esp4_decrypt_tun_node) = {
.vector_size = sizeof (u32),
.format_trace = format_esp_decrypt_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = ARRAY_LEN(esp_decrypt_error_strings),
.error_strings = esp_decrypt_error_strings,
.n_next_nodes = ESP_DECRYPT_N_NEXT,
.next_nodes = {
#define _(s,n) [ESP_DECRYPT_NEXT_##s] = n,
foreach_esp_decrypt_next
#undef _
},
.sibling_of = "esp4-decrypt",
};
VLIB_REGISTER_NODE (esp6_decrypt_tun_node) = {
@ -632,16 +633,9 @@ VLIB_REGISTER_NODE (esp6_decrypt_tun_node) = {
.vector_size = sizeof (u32),
.format_trace = format_esp_decrypt_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = ARRAY_LEN(esp_decrypt_error_strings),
.error_strings = esp_decrypt_error_strings,
.n_next_nodes = ESP_DECRYPT_N_NEXT,
.next_nodes = {
#define _(s,n) [ESP_DECRYPT_NEXT_##s] = n,
foreach_esp_decrypt_next
#undef _
},
.sibling_of = "esp6-decrypt",
};
/* *INDENT-ON* */

View File

@ -368,6 +368,9 @@ autoreply define ipsec_tunnel_protect_del
vl_api_interface_index_t sw_if_index;
};
/**
* @brief Dump all tunnel protections
*/
define ipsec_tunnel_protect_dump
{
u32 client_index;
@ -407,6 +410,10 @@ define ipsec_spd_interface_details {
};
/** \brief Add or delete IPsec tunnel interface
!!DEPRECATED!!
use the tunnel protect APIs instead
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param is_add - add IPsec tunnel interface if nonzero, else delete
@ -523,6 +530,9 @@ define ipsec_sa_details {
};
/** \brief Set new SA on IPsec interface
!! DEPRECATED !!
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param sw_if_index - index of tunnel interface

View File

@ -206,11 +206,6 @@ ipsec_rsc_in_use (ipsec_main_t * im)
"%d SA entries configured",
pool_elts (im->sad));
if (pool_elts (im->tunnel_interfaces))
return clib_error_return (0,
"%d tunnel-interface entries configured",
pool_elts (im->tunnel_interfaces));
return (NULL);
}
@ -315,9 +310,6 @@ ipsec_init (vlib_main_t * vm)
if ((error = vlib_call_init_function (vm, ipsec_cli_init)))
return error;
if ((error = vlib_call_init_function (vm, ipsec_tunnel_if_init)))
return error;
vec_validate (im->crypto_algs, IPSEC_CRYPTO_N_ALG - 1);
a = im->crypto_algs + IPSEC_CRYPTO_ALG_NONE;

View File

@ -25,7 +25,6 @@
#include <vnet/ipsec/ipsec_spd.h>
#include <vnet/ipsec/ipsec_spd_policy.h>
#include <vnet/ipsec/ipsec_sa.h>
#include <vnet/ipsec/ipsec_if.h>
typedef clib_error_t *(*add_del_sa_sess_cb_t) (u32 sa_index, u8 is_add);
typedef clib_error_t *(*check_support_cb_t) (ipsec_sa_t * sa);
@ -98,9 +97,6 @@ typedef struct
/* pool of policies */
ipsec_policy_t *policies;
/* pool of tunnel interfaces */
ipsec_tunnel_if_t *tunnel_interfaces;
uword *tunnel_index_by_key;
/* convenience */

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
#include <vnet/ip/ip.h>
#include <vnet/interface.h>
#include <vnet/fib/fib.h>
#include <vnet/ipip/ipip.h>
#include <vnet/ipsec/ipsec.h>
#include <vnet/ipsec/ipsec_tun.h>
@ -386,17 +387,18 @@ ipsec_spd_bindings_show_all (vlib_main_t * vm, ipsec_main_t * im)
/* *INDENT-ON* */
}
static void
ipsec_tunnel_show_all (vlib_main_t * vm, ipsec_main_t * im)
static walk_rc_t
ipsec_tun_protect_show_one (index_t itpi, void *ctx)
{
u32 ti;
vlib_cli_output (ctx, "%U", format_ipsec_tun_protect, itpi);
vlib_cli_output (vm, "Tunnel interfaces");
/* *INDENT-OFF* */
pool_foreach_index (ti, im->tunnel_interfaces, ({
vlib_cli_output(vm, " %U", format_ipsec_tunnel, ti);
}));
/* *INDENT-ON* */
return (WALK_CONTINUE);
}
static void
ipsec_tunnel_show_all (vlib_main_t * vm)
{
ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
}
static clib_error_t *
@ -408,7 +410,7 @@ show_ipsec_command_fn (vlib_main_t * vm,
ipsec_sa_show_all (vm, im, 0);
ipsec_spd_show_all (vm, im);
ipsec_spd_bindings_show_all (vm, im);
ipsec_tunnel_show_all (vm, im);
ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
return 0;
}
@ -537,21 +539,7 @@ show_ipsec_tunnel_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
ipsec_main_t *im = &ipsec_main;
u32 ti = ~0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "%u", &ti))
;
else
break;
}
if (~0 != ti)
vlib_cli_output (vm, "%U", format_ipsec_tunnel, ti);
else
ipsec_tunnel_show_all (vm, im);
ipsec_tunnel_show_all (vm);
return 0;
}
@ -559,7 +547,7 @@ show_ipsec_tunnel_command_fn (vlib_main_t * vm,
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_ipsec_tunnel_command, static) = {
.path = "show ipsec tunnel",
.short_help = "show ipsec tunnel [index]",
.short_help = "show ipsec tunnel",
.function = show_ipsec_tunnel_command_fn,
};
/* *INDENT-ON* */
@ -719,25 +707,44 @@ VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
};
/* *INDENT-ON* */
static u32
ipsec_tun_mk_local_sa_id (u32 ti)
{
return (0x80000000 | ti);
}
static u32
ipsec_tun_mk_remote_sa_id (u32 ti)
{
return (0xc0000000 | ti);
}
static clib_error_t *
create_ipsec_tunnel_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
ipsec_add_del_tunnel_args_t a;
ip46_address_t local_ip = ip46_address_initializer;
ip46_address_t remote_ip = ip46_address_initializer;
ipsec_crypto_alg_t crypto_alg;
ipsec_integ_alg_t integ_alg;
ipsec_sa_flags_t flags;
u32 local_spi, remote_spi, salt, table_id, fib_index;
u32 instance = ~0;
int rv;
u32 num_m_args = 0;
u8 ipv4_set = 0;
u8 ipv6_set = 0;
u8 is_add = 1;
clib_error_t *error = NULL;
ipsec_key_t rck = { 0 };
ipsec_key_t lck = { 0 };
ipsec_key_t lik = { 0 };
ipsec_key_t rik = { 0 };
clib_memset (&a, 0, sizeof (a));
a.is_add = 1;
table_id = 0;
flags = IPSEC_SA_FLAG_NONE;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
@ -746,36 +753,35 @@ create_ipsec_tunnel_command_fn (vlib_main_t * vm,
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
if (unformat
(line_input, "local-ip %U", unformat_ip46_address, &a.local_ip,
(line_input, "local-ip %U", unformat_ip46_address, &local_ip,
IP46_TYPE_ANY))
{
ip46_address_is_ip4 (&a.local_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
ip46_address_is_ip4 (&local_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
num_m_args++;
}
else
if (unformat
(line_input, "remote-ip %U", unformat_ip46_address, &a.remote_ip,
(line_input, "remote-ip %U", unformat_ip46_address, &remote_ip,
IP46_TYPE_ANY))
{
ip46_address_is_ip4 (&a.remote_ip) ? (ipv4_set = 1) : (ipv6_set =
1);
ip46_address_is_ip4 (&remote_ip) ? (ipv4_set = 1) : (ipv6_set = 1);
num_m_args++;
}
else if (unformat (line_input, "local-spi %u", &a.local_spi))
else if (unformat (line_input, "local-spi %u", &local_spi))
num_m_args++;
else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
else if (unformat (line_input, "remote-spi %u", &remote_spi))
num_m_args++;
else if (unformat (line_input, "instance %u", &a.show_instance))
a.renumber = 1;
else if (unformat (line_input, "salt 0x%x", &a.salt))
else if (unformat (line_input, "salt 0x%x", &salt))
;
else if (unformat (line_input, "udp-encap"))
a.udp_encap = 1;
flags |= IPSEC_SA_FLAG_UDP_ENCAP;
else if (unformat (line_input, "use-esn"))
a.esn = 1;
flags |= IPSEC_SA_FLAG_USE_ESN;
else if (unformat (line_input, "use-anti-replay"))
a.anti_replay = 1;
else if (unformat (line_input, "tx-table %u", &a.tx_table_id))
flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
else if (unformat (line_input, "instance %u", &instance))
;
else if (unformat (line_input, "tx-table %u", &table_id))
;
else
if (unformat
@ -786,7 +792,7 @@ create_ipsec_tunnel_command_fn (vlib_main_t * vm,
(line_input, "remote-crypto-key %U", unformat_ipsec_key, &rck))
;
else if (unformat (line_input, "crypto-alg %U",
unformat_ipsec_crypto_alg, &a.crypto_alg))
unformat_ipsec_crypto_alg, &crypto_alg))
;
else
if (unformat
@ -797,10 +803,10 @@ create_ipsec_tunnel_command_fn (vlib_main_t * vm,
(line_input, "remote-integ-key %U", unformat_ipsec_key, &rik))
;
else if (unformat (line_input, "integ-alg %U",
unformat_ipsec_integ_alg, &a.integ_alg))
unformat_ipsec_integ_alg, &integ_alg))
;
else if (unformat (line_input, "del"))
a.is_add = 0;
is_add = 0;
else
{
error = clib_error_return (0, "unknown input `%U'",
@ -818,26 +824,52 @@ create_ipsec_tunnel_command_fn (vlib_main_t * vm,
if (ipv4_set && ipv6_set)
return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
a.is_ip6 = ipv6_set;
fib_index = fib_table_find (fib_ip_proto (ipv6_set), table_id);
clib_memcpy (a.local_crypto_key, lck.data, lck.len);
a.local_crypto_key_len = lck.len;
clib_memcpy (a.remote_crypto_key, rck.data, rck.len);
a.remote_crypto_key_len = rck.len;
if (~0 == fib_index)
{
rv = VNET_API_ERROR_NO_SUCH_FIB;
goto done;
}
clib_memcpy (a.local_integ_key, lik.data, lik.len);
a.local_integ_key_len = lck.len;
clib_memcpy (a.remote_integ_key, rik.data, rik.len);
a.remote_integ_key_len = rck.len;
if (is_add)
{
// remote = input, local = output
u32 sw_if_index;
rv = ipsec_add_del_tunnel_if (&a);
/* create an ip-ip tunnel, then the two SA, then bind them */
rv =
ipip_add_tunnel (ipv6_set ? IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4,
instance, &local_ip, &remote_ip, fib_index, 0,
&sw_if_index);
rv |=
ipsec_sa_add_and_lock (ipsec_tun_mk_local_sa_id (sw_if_index),
local_spi, IPSEC_PROTOCOL_ESP, crypto_alg,
&lck, integ_alg, &lik, flags, table_id,
clib_host_to_net_u32 (salt), &local_ip,
&remote_ip, NULL);
rv |=
ipsec_sa_add_and_lock (ipsec_tun_mk_remote_sa_id (sw_if_index),
remote_spi, IPSEC_PROTOCOL_ESP, crypto_alg,
&rck, integ_alg, &rik,
(flags | IPSEC_SA_FLAG_IS_INBOUND), table_id,
clib_host_to_net_u32 (salt), &remote_ip,
&local_ip, NULL);
rv |=
ipsec_tun_protect_update_one (sw_if_index,
ipsec_tun_mk_local_sa_id (sw_if_index),
ipsec_tun_mk_remote_sa_id
(sw_if_index));
}
else
rv = 0;
switch (rv)
{
case 0:
break;
case VNET_API_ERROR_INVALID_VALUE:
if (a.is_add)
if (is_add)
error = clib_error_return (0,
"IPSec tunnel interface already exists...");
else
@ -918,13 +950,6 @@ VLIB_CLI_COMMAND (ipsec_tun_protect_cmd_node, static) =
};
/* *INDENT-ON* */
static walk_rc_t
ipsec_tun_protect_show_one (index_t itpi, void *ctx)
{
vlib_cli_output (ctx, "%U", format_ipsec_tun_protect, itpi);
return (WALK_CONTINUE);
}
static clib_error_t *
ipsec_tun_protect_show (vlib_main_t * vm,

View File

@ -334,40 +334,6 @@ done:
return (s);
}
u8 *
format_ipsec_tunnel (u8 * s, va_list * args)
{
ipsec_main_t *im = &ipsec_main;
u32 ti = va_arg (*args, u32);
ipsec_tunnel_if_t *t;
if (pool_is_free_index (im->tunnel_interfaces, ti))
{
s = format (s, "No such tunnel index: %d", ti);
goto done;
}
t = pool_elt_at_index (im->tunnel_interfaces, ti);
if (t->hw_if_index == ~0)
goto done;
s =
format (s, "%U\n", format_vnet_hw_if_index_name, im->vnet_main,
t->hw_if_index);
s = format (s, " out-bound sa: ");
s = format (s, "%U\n", format_ipsec_sa, t->output_sa_index,
IPSEC_FORMAT_BRIEF);
s = format (s, " in-bound sa: ");
s = format (s, "%U\n", format_ipsec_sa, t->input_sa_index,
IPSEC_FORMAT_BRIEF);
done:
return (s);
}
u8 *
format_ipsec_tun_protect (u8 * s, va_list * args)
{

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +0,0 @@
/*
* Copyright (c) 2015 Cisco and/or its affiliates.
* 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:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __IPSEC_IF_H__
#define __IPSEC_IF_H__
#include <vnet/ipsec/ipsec_sa.h>
typedef struct
{
/* Required for pool_get_aligned */
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
u32 input_sa_index;
u32 output_sa_index;
u32 hw_if_index;
u32 sw_if_index;
vnet_hw_interface_flags_t flags;
u32 show_instance;
} ipsec_tunnel_if_t;
typedef struct
{
u8 is_add;
u8 is_ip6;
u8 esn;
u8 anti_replay;
ip46_address_t local_ip, remote_ip;
u32 local_spi;
u32 remote_spi;
ipsec_crypto_alg_t crypto_alg;
u8 local_crypto_key_len;
u8 local_crypto_key[128];
u8 remote_crypto_key_len;
u8 remote_crypto_key[128];
ipsec_integ_alg_t integ_alg;
u8 local_integ_key_len;
u8 local_integ_key[128];
u8 remote_integ_key_len;
u8 remote_integ_key[128];
u8 renumber;
u32 show_instance;
u8 udp_encap;
u32 tx_table_id;
u32 salt;
} ipsec_add_del_tunnel_args_t;
/* *INDENT-OFF* */
typedef CLIB_PACKED
(struct {
/*
* Key fields: remote ip and spi on incoming packet
* all fields in NET byte order
*/
union {
struct {
ip4_address_t remote_ip;
u32 spi;
};
u64 as_u64;
};
}) ipsec4_tunnel_key_t;
/* *INDENT-ON* */
/* *INDENT-OFF* */
typedef CLIB_PACKED
(struct {
/*
* Key fields: remote ip and spi on incoming packet
* all fields in NET byte order
*/
ip6_address_t remote_ip;
u32 spi;
}) ipsec6_tunnel_key_t;
/* *INDENT-ON* */
extern u8 *format_ipsec4_tunnel_key (u8 * s, va_list * args);
extern u8 *format_ipsec6_tunnel_key (u8 * s, va_list * args);
extern int ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
ipsec_add_del_tunnel_args_t *
args, u32 * sw_if_index);
extern int ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args);
extern int ipsec_set_interface_sa (vnet_main_t * vnm, u32 hw_if_index,
u32 sa_id, u8 is_outbound);
extern u8 *format_ipsec_tunnel (u8 * s, va_list * args);
#endif /* __IPSEC_IF_H__ */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/

File diff suppressed because it is too large Load Diff

View File

@ -317,6 +317,20 @@ ipsec_sa_unlock (index_t sai)
fib_node_unlock (&sa->node);
}
void
ipsec_sa_lock (index_t sai)
{
ipsec_main_t *im = &ipsec_main;
ipsec_sa_t *sa;
if (INDEX_INVALID == sai)
return;
sa = pool_elt_at_index (im->sad, sai);
fib_node_lock (&sa->node);
}
index_t
ipsec_sa_find_and_lock (u32 id)
{

View File

@ -211,6 +211,7 @@ extern int ipsec_sa_add_and_lock (u32 id,
extern index_t ipsec_sa_find_and_lock (u32 id);
extern int ipsec_sa_unlock_id (u32 id);
extern void ipsec_sa_unlock (index_t sai);
extern void ipsec_sa_lock (index_t sai);
extern void ipsec_sa_clear (index_t sai);
extern void ipsec_sa_set_crypto_alg (ipsec_sa_t * sa,
ipsec_crypto_alg_t crypto_alg);

View File

@ -148,6 +148,7 @@ ipsec_tun_protect_config (ipsec_main_t * im,
ipsec_tun_protect_t * itp, u32 sa_out, u32 * sas_in)
{
ipsec_sa_t *sa;
index_t sai;
u32 ii;
itp->itp_n_sa_in = vec_len (sas_in);
@ -155,7 +156,13 @@ ipsec_tun_protect_config (ipsec_main_t * im,
itp->itp_in_sas[ii] = sas_in[ii];
itp->itp_out_sa = sa_out;
ipsec_sa_lock (itp->itp_out_sa);
/* *INDENT-OFF* */
FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai,
({
ipsec_sa_lock(sai);
}));
FOR_EACH_IPSEC_PROTECT_INPUT_SA(itp, sa,
({
if (ipsec_sa_is_set_IS_TUNNEL (sa))
@ -183,7 +190,6 @@ ipsec_tun_protect_config (ipsec_main_t * im,
* enable the encrypt feature for egress.
*/
ipsec_tun_protect_feature_set (itp, 1);
}
static void
@ -220,11 +226,117 @@ ipsec_tun_protect_find (u32 sw_if_index)
return (ipsec_protect_db.tunnels[sw_if_index]);
}
int
ipsec_tun_protect_update_one (u32 sw_if_index, u32 sa_out, u32 sa_in)
{
u32 *sas_in = NULL;
int rv;
vec_add1 (sas_in, sa_in);
rv = ipsec_tun_protect_update (sw_if_index, sa_out, sas_in);
return (rv);
}
int
ipsec_tun_protect_update_out (u32 sw_if_index, u32 sa_out)
{
u32 itpi, *sas_in, sai, *saip;
ipsec_tun_protect_t *itp;
ipsec_main_t *im;
int rv;
sas_in = NULL;
rv = 0;
im = &ipsec_main;
vec_validate_init_empty (ipsec_protect_db.tunnels, sw_if_index,
INDEX_INVALID);
itpi = ipsec_protect_db.tunnels[sw_if_index];
if (INDEX_INVALID == itpi)
{
return (VNET_API_ERROR_INVALID_INTERFACE);
}
itp = pool_elt_at_index (ipsec_protect_pool, itpi);
/* *INDENT-0FF* */
FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai, (
{
ipsec_sa_lock (sai);
vec_add1 (sas_in, sai);
}
));
/* *INDENT-ON* */
sa_out = ipsec_sa_find_and_lock (sa_out);
if (~0 == sa_out)
{
rv = VNET_API_ERROR_INVALID_VALUE;
goto out;
}
ipsec_tun_protect_unconfig (im, itp);
ipsec_tun_protect_config (im, itp, sa_out, sas_in);
ipsec_sa_unlock (sa_out);
vec_foreach (saip, sas_in) ipsec_sa_unlock (*saip);
out:
vec_free (sas_in);
return (rv);
}
int
ipsec_tun_protect_update_in (u32 sw_if_index, u32 sa_in)
{
u32 itpi, *sas_in, sa_out;
ipsec_tun_protect_t *itp;
ipsec_main_t *im;
int rv;
sas_in = NULL;
rv = 0;
im = &ipsec_main;
vec_validate_init_empty (ipsec_protect_db.tunnels, sw_if_index,
INDEX_INVALID);
itpi = ipsec_protect_db.tunnels[sw_if_index];
if (INDEX_INVALID == itpi)
{
return (VNET_API_ERROR_INVALID_INTERFACE);
}
sa_in = ipsec_sa_find_and_lock (sa_in);
if (~0 == sa_in)
{
rv = VNET_API_ERROR_INVALID_VALUE;
goto out;
}
vec_add1 (sas_in, sa_in);
itp = pool_elt_at_index (ipsec_protect_pool, itpi);
sa_out = itp->itp_out_sa;
ipsec_sa_lock (sa_out);
ipsec_tun_protect_unconfig (im, itp);
ipsec_tun_protect_config (im, itp, sa_out, sas_in);
ipsec_sa_unlock (sa_out);
ipsec_sa_unlock (sa_in);
out:
vec_free (sas_in);
return (rv);
}
int
ipsec_tun_protect_update (u32 sw_if_index, u32 sa_out, u32 * sas_in)
{
u32 itpi, ii;
ipsec_tun_protect_t *itp;
u32 itpi, ii, *saip;
ipsec_main_t *im;
int rv;
@ -330,7 +442,10 @@ ipsec_tun_protect_update (u32 sw_if_index, u32 sa_out, u32 * sas_in)
ipsec_tun_protect_config (im, itp, sa_out, sas_in);
}
ipsec_sa_unlock (sa_out);
vec_foreach (saip, sas_in) ipsec_sa_unlock (*saip);
vec_free (sas_in);
out:
return (rv);
}

View File

@ -17,6 +17,36 @@
#include <vnet/ipsec/ipsec.h>
/* *INDENT-OFF* */
typedef CLIB_PACKED(struct {
/*
* Key fields: remote ip and spi on incoming packet
* all fields in NET byte order
*/
union {
struct {
ip4_address_t remote_ip;
u32 spi;
};
u64 as_u64;
};
}) ipsec4_tunnel_key_t;
/* *INDENT-ON* */
/* *INDENT-OFF* */
typedef CLIB_PACKED(struct {
/*
* Key fields: remote ip and spi on incoming packet
* all fields in NET byte order
*/
ip6_address_t remote_ip;
u32 spi;
}) ipsec6_tunnel_key_t;
/* *INDENT-ON* */
extern u8 *format_ipsec4_tunnel_key (u8 * s, va_list * args);
extern u8 *format_ipsec6_tunnel_key (u8 * s, va_list * args);
typedef enum ipsec_protect_flags_t_
{
IPSEC_PROTECT_L2 = (1 << 0),
@ -66,8 +96,13 @@ typedef struct ipsec_tun_protect_t_
} \
}
extern int ipsec_tun_protect_update_one (u32 sw_if_index, u32 sa_out,
u32 sa_in);
extern int ipsec_tun_protect_update (u32 sw_if_index, u32 sa_out,
u32 sa_ins[2]);
u32 * sa_ins);
extern int ipsec_tun_protect_update_in (u32 sw_if_index, u32 sa_in);
extern int ipsec_tun_protect_update_out (u32 sw_if_index, u32 sa_out);
extern int ipsec_tun_protect_del (u32 sw_if_index);
typedef walk_rc_t (*ipsec_tun_protect_walk_cb_t) (index_t itpi, void *arg);

View File

@ -68,6 +68,7 @@ typedef struct
};
u8 is_ip6;
u32 seq;
u32 sa_index;
} ipsec_tun_protect_input_trace_t;
static u8 *
@ -79,11 +80,11 @@ format_ipsec_tun_protect_input_trace (u8 * s, va_list * args)
va_arg (*args, ipsec_tun_protect_input_trace_t *);
if (t->is_ip6)
s = format (s, "IPSec: %U seq %u",
format_ipsec6_tunnel_key, &t->key6, t->seq);
s = format (s, "IPSec: %U seq %u sa %d",
format_ipsec6_tunnel_key, &t->key6, t->seq, t->sa_index);
else
s = format (s, "IPSec: %U seq %u",
format_ipsec4_tunnel_key, &t->key4, t->seq);
s = format (s, "IPSec: %U seq %u sa %d",
format_ipsec4_tunnel_key, &t->key4, t->seq, t->sa_index);
return s;
}
@ -376,9 +377,9 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
else
clib_memcpy (&tr->key4, &key40, sizeof (tr->key4));
tr->is_ip6 = is_ip6;
tr->seq =
len0 >=
sizeof (*esp0) ? clib_host_to_net_u32 (esp0->seq) : ~0;
tr->seq = (len0 >= sizeof (*esp0) ?
clib_host_to_net_u32 (esp0->seq) : ~0);
tr->sa_index = vnet_buffer (b[0])->ipsec.sad_index;
}
}

View File

@ -84,7 +84,7 @@ class IPsecIPv6Params(object):
self.nat_header = None
def mk_scapy_crpyt_key(p):
def mk_scapy_crypt_key(p):
if p.crypt_algo == "AES-GCM":
return p.crypt_key + struct.pack("!I", p.salt)
else:
@ -95,7 +95,7 @@ def config_tun_params(p, encryption_type, tun_if):
ip_class_by_addr_type = {socket.AF_INET: IP, socket.AF_INET6: IPv6}
use_esn = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
IPSEC_API_SAD_FLAG_USE_ESN))
crypt_key = mk_scapy_crpyt_key(p)
crypt_key = mk_scapy_crypt_key(p)
p.scapy_tun_sa = SecurityAssociation(
encryption_type, spi=p.vpp_tun_spi,
crypt_algo=p.crypt_algo,
@ -121,7 +121,7 @@ def config_tun_params(p, encryption_type, tun_if):
def config_tra_params(p, encryption_type):
use_esn = bool(p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.
IPSEC_API_SAD_FLAG_USE_ESN))
crypt_key = mk_scapy_crpyt_key(p)
crypt_key = mk_scapy_crypt_key(p)
p.scapy_tra_sa = SecurityAssociation(
encryption_type,
spi=p.vpp_tra_spi,
@ -250,7 +250,6 @@ class IpsecTcp(object):
def verify_tcp_checksum(self):
self.vapi.cli("test http server")
p = self.params[socket.AF_INET]
config_tun_params(p, self.encryption_type, self.tun_if)
send = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
p.scapy_tun_sa.encrypt(IP(src=p.remote_tun_if_host,
dst=self.tun_if.local_ip4) /
@ -362,7 +361,7 @@ class IpsecTra4(object):
bogus_sa = SecurityAssociation(self.encryption_type,
p.vpp_tra_spi,
crypt_algo=p.crypt_algo,
crypt_key=mk_scapy_crpyt_key(p)[::-1],
crypt_key=mk_scapy_crypt_key(p)[::-1],
auth_algo=p.auth_algo,
auth_key=p.auth_key[::-1])
pkt = (Ether(src=self.tra_if.remote_mac,
@ -718,7 +717,6 @@ class IpsecTun4(object):
if not n_rx:
n_rx = count
try:
config_tun_params(p, self.encryption_type, self.tun_if)
send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if,
src=p.remote_tun_if_host,
dst=self.pg1.remote_ip4,
@ -745,7 +743,6 @@ class IpsecTun4(object):
sw_if_index=self.tun_if.sw_if_index, enable_ip4=True)
try:
config_tun_params(p, self.encryption_type, self.tun_if)
send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if,
src=p.remote_tun_if_host,
dst=self.pg1.remote_ip4,
@ -773,7 +770,6 @@ class IpsecTun4(object):
def verify_tun_64(self, p, count=1):
self.vapi.cli("clear errors")
try:
config_tun_params(p, self.encryption_type, self.tun_if)
send_pkts = self.gen_encrypt_pkts6(p.scapy_tun_sa, self.tun_if,
src=p.remote_tun_if_host6,
dst=self.pg1.remote_ip6,
@ -887,7 +883,6 @@ class IpsecTun6(object):
self.vapi.cli("clear errors")
self.vapi.cli("clear ipsec sa")
config_tun_params(p_in, self.encryption_type, self.tun_if)
send_pkts = self.gen_encrypt_pkts6(p_in.scapy_tun_sa, self.tun_if,
src=p_in.remote_tun_if_host,
dst=self.pg1.remote_ip6,
@ -901,8 +896,6 @@ class IpsecTun6(object):
if not p_out:
p_out = p_in
try:
config_tun_params(p_in, self.encryption_type, self.tun_if)
config_tun_params(p_out, self.encryption_type, self.tun_if)
send_pkts = self.gen_encrypt_pkts6(p_in.scapy_tun_sa, self.tun_if,
src=p_in.remote_tun_if_host,
dst=self.pg1.remote_ip6,
@ -929,7 +922,6 @@ class IpsecTun6(object):
sw_if_index=self.tun_if.sw_if_index, enable_ip6=True)
try:
config_tun_params(p, self.encryption_type, self.tun_if)
send_pkts = self.gen_encrypt_pkts6(p.scapy_tun_sa, self.tun_if,
src=p.remote_tun_if_host,
dst=self.pg1.remote_ip6,
@ -958,7 +950,6 @@ class IpsecTun6(object):
""" ipsec 4o6 tunnel basic test """
self.vapi.cli("clear errors")
try:
config_tun_params(p, self.encryption_type, self.tun_if)
send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if,
src=p.remote_tun_if_host4,
dst=self.pg1.remote_ip4,

View File

@ -88,6 +88,7 @@ class ConfigIpsecAH(TemplateIpsec):
config_tra_params(p, self.encryption_type)
for p in params:
self.config_ah_tun(p)
config_tun_params(p, self.encryption_type, self.tun_if)
for p in params:
d = DpoProto.DPO_PROTO_IP6 if p.is_ipv6 else DpoProto.DPO_PROTO_IP4
r = VppIpRoute(self, p.remote_tun_if_host, p.addr_len,

View File

@ -7,7 +7,7 @@ from parameterized import parameterized
from framework import VppTestRunner
from template_ipsec import IpsecTra46Tests, IpsecTun46Tests, TemplateIpsec, \
IpsecTcpTests, IpsecTun4Tests, IpsecTra4Tests, config_tra_params, \
IPsecIPv4Params, IPsecIPv6Params, \
config_tun_params, IPsecIPv4Params, IPsecIPv6Params, \
IpsecTra4, IpsecTun4, IpsecTra6, IpsecTun6
from vpp_ipsec import VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSA,\
VppIpsecSpdItfBinding
@ -71,6 +71,7 @@ class ConfigIpsecESP(TemplateIpsec):
config_tra_params(p, self.encryption_type)
for p in params:
self.config_esp_tun(p)
config_tun_params(p, self.encryption_type, self.tun_if)
for p in params:
d = DpoProto.DPO_PROTO_IP6 if p.is_ipv6 else DpoProto.DPO_PROTO_IP4

File diff suppressed because it is too large Load Diff

View File

@ -706,6 +706,7 @@ class TestExceptionPuntSocket(TestPuntSocket):
def setUp(self):
super(TestExceptionPuntSocket, self).setUp()
self.create_pg_interfaces(range(2))
for i in self.pg_interfaces:
i.config_ip4()
i.resolve_arp()
@ -805,7 +806,7 @@ class TestExceptionPuntSocket(TestPuntSocket):
IPSEC_API_INTEG_ALG_SHA1_96),
b"0123456701234567",
b"0123456701234567").add_vpp_config()
VppIpsecTunInterface(self, self.pg0, 1001, 1001,
VppIpsecTunInterface(self, self.pg1, 1000, 1000,
(VppEnum.vl_api_ipsec_crypto_alg_t.
IPSEC_API_CRYPTO_ALG_AES_CBC_128),
b"0123456701234567",
@ -821,8 +822,12 @@ class TestExceptionPuntSocket(TestPuntSocket):
# adn SPI=0
#
cfgs = dict()
cfgs['ipsec4-no-such-tunnel'] = {'spi': 99, 'udp': False}
cfgs['ipsec4-spi-o-udp-0'] = {'spi': 0, 'udp': True}
cfgs['ipsec4-no-such-tunnel'] = {'spi': 99,
'udp': False,
'itf': self.pg0}
cfgs['ipsec4-spi-o-udp-0'] = {'spi': 0,
'udp': True,
'itf': self.pg1}
#
# find the VPP ID for these punt exception reasin
@ -850,9 +855,10 @@ class TestExceptionPuntSocket(TestPuntSocket):
# create packet streams for 'no-such-tunnel' exception
#
for cfg in cfgs.values():
pkt = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4))
pkt = (Ether(src=cfg['itf'].remote_mac,
dst=cfg['itf'].local_mac) /
IP(src=cfg['itf'].remote_ip4,
dst=cfg['itf'].local_ip4))
if (cfg['udp']):
pkt = pkt / UDP(sport=666, dport=4500)
pkt = (pkt / ESP(spi=cfg['spi'], seq=3) /
@ -863,7 +869,7 @@ class TestExceptionPuntSocket(TestPuntSocket):
# send packets for each SPI we expect to be punted
#
for cfg in cfgs.values():
self.send_and_assert_no_replies(self.pg0, cfg['pkts'])
self.send_and_assert_no_replies(cfg['itf'], cfg['pkts'])
#
# verify the punted packets arrived on the associated socket

View File

@ -48,3 +48,11 @@ class VppGreInterface(VppInterface):
def query_vpp_config(self):
return (self.test.vapi.gre_tunnel_dump(
sw_if_index=self._sw_if_index))
@property
def remote_ip(self):
return self.t_dst
@property
def local_ip(self):
return self.t_src

View File

@ -38,3 +38,11 @@ class VppIpIpTunInterface(VppTunnelInterface):
def object_id(self):
return "ipip-%d" % self._sw_if_index
@property
def remote_ip(self):
return self.dst
@property
def local_ip(self):
return self.src

View File

@ -10,7 +10,8 @@ class VppIpsecTunInterface(VppTunnelInterface):
remote_spi, crypto_alg, local_crypto_key, remote_crypto_key,
integ_alg, local_integ_key, remote_integ_key, salt=0,
udp_encap=False,
is_ip6=False):
is_ip6=False,
dst=None):
super(VppIpsecTunInterface, self).__init__(test, parent_if)
self.local_spi = local_spi
self.remote_spi = remote_spi
@ -27,6 +28,8 @@ class VppIpsecTunInterface(VppTunnelInterface):
else:
self.local_ip = self.parent_if.local_ip4
self.remote_ip = self.parent_if.remote_ip4
if dst:
self.remote_ip = dst
self.udp_encap = udp_encap
def add_vpp_config(self):

View File

@ -1717,7 +1717,7 @@ class VppPapiProvider(object):
remote_crypto_key, integ_alg, local_integ_key,
remote_integ_key, is_add=1, esn=0, salt=0,
anti_replay=1, renumber=0,
udp_encap=0, show_instance=0):
udp_encap=0, show_instance=0xffffffff):
return self.api(
self.papi.ipsec_tunnel_if_add_del,
{