IPSEC: tunnel scaling - don't stack the inbould SA 32/18632/3
authorNeale Ranns <nranns@cisco.com>
Tue, 2 Apr 2019 10:15:40 +0000 (10:15 +0000)
committerDamjan Marion <dmarion@me.com>
Tue, 2 Apr 2019 14:10:10 +0000 (14:10 +0000)
Change-Id: I0b47590400aebea09aa1b27de753be638e1ba870
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vat/api_format.c
src/vnet/ipsec/ipsec_format.c
src/vnet/ipsec/ipsec_if.c
src/vnet/ipsec/ipsec_sa.c
src/vnet/ipsec/ipsec_sa.h
src/vpp/api/custom_dump.c
src/vpp/api/types.c

index bdfa8c1..0e2fec3 100644 (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);
+  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;
 }
 
index a861655..c91a9ba 100644 (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);
index bfdc2bb..3c1f845 100644 (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);
index 9f2d850..0ca2f37 100644 (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
index cfb44b9..66bdcc7 100644 (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_
 {
index fac2aa2..9e150e9 100644 (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)                                           \
index e36b8dd..427e9f0 100644 (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;
 }