From 2b5ba9501c3dda3645bf01eb53b2821471f2a946 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Tue, 2 Apr 2019 10:15:40 +0000 Subject: IPSEC: tunnel scaling - don't stack the inbould SA Change-Id: I0b47590400aebea09aa1b27de753be638e1ba870 Signed-off-by: Neale Ranns --- src/vat/api_format.c | 173 +++++++++++++++++++++++++++++++----------- src/vnet/ipsec/ipsec_format.c | 15 ++-- src/vnet/ipsec/ipsec_if.c | 2 +- src/vnet/ipsec/ipsec_sa.c | 16 +--- src/vnet/ipsec/ipsec_sa.h | 1 + src/vpp/api/custom_dump.c | 43 +++++++++++ src/vpp/api/types.c | 8 +- 7 files changed, 189 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/vat/api_format.c b/src/vat/api_format.c index bdfa8c1b56a..0e2fec32218 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -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); + if (count > 1) + { + /* Turn on async mode */ + vam->async_mode = 1; + vam->async_errors = 0; + before = vat_time_now (vam); + } - mp->is_add = is_add; - mp->esn = esn; - mp->anti_replay = anti_replay; + for (jj = 0; jj < count; jj++) + { + M (IPSEC_TUNNEL_IF_ADD_DEL, mp); - clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip)); - clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip)); + mp->is_add = is_add; + mp->esn = esn; + mp->anti_replay = anti_replay; - mp->local_spi = htonl (local_spi); - mp->remote_spi = htonl (remote_spi); - mp->crypto_alg = (u8) crypto_alg; + if (jj > 0) + increment_vl_address (&remote_ip); - 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); - } + clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip)); + clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip)); - 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->local_spi = htonl (local_spi + jj); + mp->remote_spi = htonl (remote_spi + jj); + mp->crypto_alg = (u8) crypto_alg; - mp->integ_alg = (u8) integ_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->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_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->remote_integ_key_len = 0; - if (rik) + /* When testing multiple add/del ops, use a control-ping to sync */ + if (count > 1) { - 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); - } + vl_api_control_ping_t *mp_ping; + f64 after; + f64 timeout; - if (renumber) + /* 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 { - mp->renumber = renumber; - mp->show_instance = ntohl (instance); + /* Wait for a reply... */ + W (ret); + return ret; } - S (mp); - W (ret); return ret; } diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c index a8616555629..c91a9ba632e 100644 --- a/src/vnet/ipsec/ipsec_format.c +++ b/src/vnet/ipsec/ipsec_format.c @@ -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); diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c index bfdc2bb6814..3c1f84576d4 100644 --- a/src/vnet/ipsec/ipsec_if.c +++ b/src/vnet/ipsec/ipsec_if.c @@ -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); diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c index 9f2d8505c35..0ca2f376c67 100644 --- a/src/vnet/ipsec/ipsec_sa.c +++ b/src/vnet/ipsec/ipsec_sa.c @@ -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 diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index cfb44b9e86d..66bdcc72308 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -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_ { diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index fac2aa26c0d..9e150e91a7b 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -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) \ diff --git a/src/vpp/api/types.c b/src/vpp/api/types.c index e36b8dd6781..427e9f0da3a 100644 --- a/src/vpp/api/types.c +++ b/src/vpp/api/types.c @@ -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; } -- cgit 1.2.3-korg