IPSEC: tunnel scaling - don't stack the inbould SA

Change-Id: I0b47590400aebea09aa1b27de753be638e1ba870
Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
Neale Ranns
2019-04-02 10:15:40 +00:00
committed by Damjan Marion
parent ea5bb7761d
commit 2b5ba9501c
7 changed files with 194 additions and 74 deletions

View File

@ -712,6 +712,25 @@ increment_v4_address (ip4_address_t * a)
a->as_u32 = ntohl (v);
}
static void
increment_vl_v4_address (vl_api_ip4_address_t * a)
{
u32 v;
v = *(u32 *) a;
v = ntohl (v);
v++;
v = ntohl (v);
clib_memcpy (a, &v, sizeof (v));
}
static void
increment_vl_address (vl_api_address_t * a)
{
if (ADDRESS_IP4 == a->af)
increment_vl_v4_address (&a->un.ip4);
}
static void
increment_v6_address (ip6_address_t * a)
{
@ -15030,11 +15049,13 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam)
u8 *lik = NULL, *rik = NULL;
vl_api_address_t local_ip = { 0 };
vl_api_address_t remote_ip = { 0 };
f64 before = 0;
u8 is_add = 1;
u8 esn = 0;
u8 anti_replay = 0;
u8 renumber = 0;
u32 instance = ~0;
u32 count = 1, jj;
int ret;
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
@ -15043,8 +15064,10 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam)
is_add = 0;
else if (unformat (i, "esn"))
esn = 1;
else if (unformat (i, "anti_replay"))
else if (unformat (i, "anti-replay"))
anti_replay = 1;
else if (unformat (i, "count %d", &count))
;
else if (unformat (i, "local_spi %d", &local_spi))
;
else if (unformat (i, "remote_spi %d", &remote_spi))
@ -15095,65 +15118,123 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam)
}
}
M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
mp->is_add = is_add;
mp->esn = esn;
mp->anti_replay = anti_replay;
clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
mp->local_spi = htonl (local_spi);
mp->remote_spi = htonl (remote_spi);
mp->crypto_alg = (u8) crypto_alg;
mp->local_crypto_key_len = 0;
if (lck)
if (count > 1)
{
mp->local_crypto_key_len = vec_len (lck);
if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
/* Turn on async mode */
vam->async_mode = 1;
vam->async_errors = 0;
before = vat_time_now (vam);
}
mp->remote_crypto_key_len = 0;
if (rck)
for (jj = 0; jj < count; jj++)
{
mp->remote_crypto_key_len = vec_len (rck);
if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
mp->is_add = is_add;
mp->esn = esn;
mp->anti_replay = anti_replay;
if (jj > 0)
increment_vl_address (&remote_ip);
clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
mp->local_spi = htonl (local_spi + jj);
mp->remote_spi = htonl (remote_spi + jj);
mp->crypto_alg = (u8) crypto_alg;
mp->local_crypto_key_len = 0;
if (lck)
{
mp->local_crypto_key_len = vec_len (lck);
if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
}
mp->remote_crypto_key_len = 0;
if (rck)
{
mp->remote_crypto_key_len = vec_len (rck);
if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
}
mp->integ_alg = (u8) integ_alg;
mp->local_integ_key_len = 0;
if (lik)
{
mp->local_integ_key_len = vec_len (lik);
if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
mp->local_integ_key_len = sizeof (mp->local_integ_key);
clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
}
mp->remote_integ_key_len = 0;
if (rik)
{
mp->remote_integ_key_len = vec_len (rik);
if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
}
if (renumber)
{
mp->renumber = renumber;
mp->show_instance = ntohl (instance);
}
S (mp);
}
mp->integ_alg = (u8) integ_alg;
mp->local_integ_key_len = 0;
if (lik)
/* When testing multiple add/del ops, use a control-ping to sync */
if (count > 1)
{
mp->local_integ_key_len = vec_len (lik);
if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
mp->local_integ_key_len = sizeof (mp->local_integ_key);
clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
vl_api_control_ping_t *mp_ping;
f64 after;
f64 timeout;
/* Shut off async mode */
vam->async_mode = 0;
MPING (CONTROL_PING, mp_ping);
S (mp_ping);
timeout = vat_time_now (vam) + 1.0;
while (vat_time_now (vam) < timeout)
if (vam->result_ready == 1)
goto out;
vam->retval = -99;
out:
if (vam->retval == -99)
errmsg ("timeout");
if (vam->async_errors > 0)
{
errmsg ("%d asynchronous errors", vam->async_errors);
vam->retval = -98;
}
vam->async_errors = 0;
after = vat_time_now (vam);
/* slim chance, but we might have eaten SIGTERM on the first iteration */
if (jj > 0)
count = jj;
print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
count, after - before, count / (after - before));
}
else
{
/* Wait for a reply... */
W (ret);
return ret;
}
mp->remote_integ_key_len = 0;
if (rik)
{
mp->remote_integ_key_len = vec_len (rik);
if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
}
if (renumber)
{
mp->renumber = renumber;
mp->show_instance = ntohl (instance);
}
S (mp);
W (ret);
return ret;
}

View File

@ -294,11 +294,16 @@ format_ipsec_sa (u8 * s, va_list * args)
tx_table_id,
format_ip46_address, &sa->tunnel_src_addr, IP46_TYPE_ANY,
format_ip46_address, &sa->tunnel_dst_addr, IP46_TYPE_ANY);
s = format (s, "\n resovle via fib-entry: %d", sa->fib_entry_index);
s = format (s, "\n stacked on:");
s =
format (s, "\n %U", format_dpo_id, &sa->dpo[IPSEC_PROTOCOL_ESP],
6);
if (!ipsec_sa_is_set_IS_INBOUND (sa))
{
s =
format (s, "\n resovle via fib-entry: %d",
sa->fib_entry_index);
s = format (s, "\n stacked on:");
s =
format (s, "\n %U", format_dpo_id,
&sa->dpo[IPSEC_PROTOCOL_ESP], 6);
}
}
return (s);

View File

@ -306,7 +306,7 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
&crypto_key,
args->integ_alg,
&integ_key,
flags,
(flags | IPSEC_SA_FLAG_IS_INBOUND),
args->tx_table_id,
&args->remote_ip,
&args->local_ip, &t->input_sa_index);

View File

@ -149,6 +149,7 @@ ipsec_sa_add (u32 id,
sa->spi = spi;
sa->stat_index = sa_index;
sa->protocol = proto;
sa->flags = flags;
ipsec_sa_set_crypto_alg (sa, crypto_alg);
clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
ipsec_sa_set_integ_alg (sa, integ_alg);
@ -156,17 +157,6 @@ ipsec_sa_add (u32 id,
ip46_address_copy (&sa->tunnel_src_addr, tun_src);
ip46_address_copy (&sa->tunnel_dst_addr, tun_dst);
if (flags & IPSEC_SA_FLAG_USE_ESN)
ipsec_sa_set_USE_ESN (sa);
if (flags & IPSEC_SA_FLAG_USE_ANTI_REPLAY)
ipsec_sa_set_USE_ANTI_REPLAY (sa);
if (flags & IPSEC_SA_FLAG_IS_TUNNEL)
ipsec_sa_set_IS_TUNNEL (sa);
if (flags & IPSEC_SA_FLAG_IS_TUNNEL_V6)
ipsec_sa_set_IS_TUNNEL_V6 (sa);
if (flags & IPSEC_SA_FLAG_UDP_ENCAP)
ipsec_sa_set_UDP_ENCAP (sa);
err = ipsec_check_support_cb (im, sa);
if (err)
{
@ -182,7 +172,7 @@ ipsec_sa_add (u32 id,
return VNET_API_ERROR_SYSCALL_ERROR_1;
}
if (ipsec_sa_is_set_IS_TUNNEL (sa))
if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa))
{
fib_protocol_t fproto = (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
@ -280,7 +270,7 @@ ipsec_sa_del (u32 id)
if (err)
return VNET_API_ERROR_SYSCALL_ERROR_1;
if (ipsec_sa_is_set_IS_TUNNEL (sa))
if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa))
{
fib_entry_child_remove (sa->fib_entry_index, sa->sibling);
fib_table_entry_special_remove

View File

@ -91,6 +91,7 @@ typedef struct ipsec_key_t_
_ (8, IS_TUNNEL_V6, "tunnel-v6") \
_ (16, UDP_ENCAP, "udp-encap") \
_ (32, IS_GRE, "GRE") \
_ (64, IS_INBOUND, "inboud") \
typedef enum ipsec_sad_flags_t_
{

View File

@ -3307,6 +3307,48 @@ static void *vl_api_lisp_eid_table_map_dump_t_print
FINISH;
}
static void *vl_api_ipsec_tunnel_if_add_del_t_print
(vl_api_ipsec_tunnel_if_add_del_t * mp, void *handle)
{
u8 *s;
s = format (0, "SCRIPT: ipsec_tunnel_if_add_del ");
if (mp->esn)
s = format (s, "esn");
if (mp->anti_replay)
s = format (s, "anti-replay");
if (mp->udp_encap)
s = format (s, "udp-encap");
s = format (s, "local-ip %U ", format_vl_api_address, &mp->remote_ip);
s = format (s, "remote-ip %U ", format_vl_api_address, &mp->local_ip);
s = format (s, "tx-table-id %d ", ntohl (mp->tx_table_id));
s = format (s, "local-spi %d ", ntohl (mp->local_spi));
s = format (s, "remote-spi %d ", ntohl (mp->remote_spi));
s = format (s, "local-crypto-key-len %d ", mp->local_crypto_key_len);
s = format (s, "local-crypto-key %U ", format_hex_bytes,
mp->local_crypto_key, mp->local_crypto_key_len, 0);
s = format (s, "remote-crypto-key-len %d ", mp->remote_crypto_key_len);
s = format (s, "remote-crypto-key %U ", format_hex_bytes,
mp->remote_crypto_key, mp->remote_crypto_key_len, 0);
s = format (s, "local-integ-key-len %d ", mp->local_integ_key_len);
s = format (s, "local-integ-key %U ", format_hex_bytes,
mp->local_integ_key, mp->local_integ_key_len, 0);
s = format (s, "remote-integ-key-len %d ", mp->remote_integ_key_len);
s = format (s, "remote-integ-key %U ", format_hex_bytes,
mp->remote_integ_key, mp->remote_integ_key_len, 0);
if (mp->is_add == 0)
s = format (s, "del ");
FINISH;
}
static void *vl_api_ipsec_gre_tunnel_add_del_t_print
(vl_api_ipsec_gre_tunnel_add_del_t * mp, void *handle)
{
@ -3899,6 +3941,7 @@ _(SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state) \
_(SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state) \
_(LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable) \
_(LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable) \
_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \
_(IPSEC_GRE_TUNNEL_ADD_DEL, ipsec_gre_tunnel_add_del) \
_(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump) \
_(DELETE_SUBIF, delete_subif) \

View File

@ -25,9 +25,9 @@ format_vl_api_address (u8 * s, va_list * args)
const vl_api_address_t *addr = va_arg (*args, vl_api_address_t *);
if (ADDRESS_IP6 == clib_net_to_host_u32 (addr->af))
s = format (s, "ip6:%U", format_ip6_address, addr->un.ip6);
s = format (s, "%U", format_ip6_address, addr->un.ip6);
else
s = format (s, "ip4:%U", format_ip4_address, addr->un.ip4);
s = format (s, "%U", format_ip4_address, addr->un.ip4);
return s;
}
@ -40,9 +40,9 @@ format_vl_api_address_union (u8 * s, va_list * args)
vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
if (ADDRESS_IP6 == af)
s = format (s, "ip6:%U", format_ip6_address, addr->ip6);
s = format (s, "%U", format_ip6_address, addr->ip6);
else
s = format (s, "ip4:%U", format_ip4_address, addr->ip4);
s = format (s, "%U", format_ip4_address, addr->ip4);
return s;
}