LCOV - code coverage report
Current view: top level - plugins/unittest - ipsec_test.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 15 192 7.8 %
Date: 2023-07-05 22:20:52 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <vnet/ipsec/ipsec.h>
      17             : #include <vnet/ipsec/ipsec_sa.h>
      18             : #include <vnet/ipsec/ipsec_output.h>
      19             : 
      20             : static clib_error_t *
      21         158 : test_ipsec_command_fn (vlib_main_t * vm,
      22             :                        unformat_input_t * input, vlib_cli_command_t * cmd)
      23             : {
      24             :   u64 seq_num;
      25             :   u32 sa_id;
      26             : 
      27         158 :   sa_id = ~0;
      28         158 :   seq_num = 0;
      29             : 
      30         474 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
      31             :     {
      32         316 :       if (unformat (input, "sa %d", &sa_id))
      33             :         ;
      34         158 :       else if (unformat (input, "seq 0x%llx", &seq_num))
      35             :         ;
      36             :       else
      37           0 :         break;
      38             :     }
      39             : 
      40         158 :   if (~0 != sa_id)
      41             :     {
      42             :       ipsec_sa_t *sa;
      43             :       u32 sa_index;
      44             : 
      45         158 :       sa_index = ipsec_sa_find_and_lock (sa_id);
      46         158 :       sa = ipsec_sa_get (sa_index);
      47             : 
      48         158 :       sa->seq = seq_num & 0xffffffff;
      49         158 :       sa->seq_hi = seq_num >> 32;
      50             : 
      51         158 :       ipsec_sa_unlock (sa_index);
      52             :     }
      53             :   else
      54             :     {
      55           0 :       return clib_error_return (0, "unknown SA `%U'",
      56             :                                 format_unformat_error, input);
      57             :     }
      58             : 
      59         158 :   return (NULL);
      60             : }
      61             : 
      62             : static clib_error_t *
      63           0 : test_ipsec_spd_outbound_perf_command_fn (vlib_main_t *vm,
      64             :                                          unformat_input_t *input,
      65             :                                          vlib_cli_command_t *cmd)
      66             : {
      67           0 :   clib_error_t *err = 0;
      68           0 :   ipsec_crypto_alg_t crypto_alg = IPSEC_CRYPTO_ALG_AES_GCM_128;
      69           0 :   ipsec_integ_alg_t integ_alg = IPSEC_INTEG_ALG_NONE;
      70           0 :   ipsec_protocol_t proto = IPSEC_PROTOCOL_ESP;
      71           0 :   ipsec_sa_flags_t sa_flags = IPSEC_SA_FLAG_NONE;
      72           0 :   ipsec_key_t ck = { 0 };
      73           0 :   u8 key_data[] = { 31, 32, 33, 34, 35, 36, 37, 38,
      74             :                     39, 30, 31, 32, 33, 34, 35, 36 };
      75           0 :   ipsec_mk_key (&ck, key_data, 16);
      76           0 :   ipsec_key_t ik = { 0 };
      77           0 :   u32 sa_id = 123456, spi = 654321, salt = 1234, sai;
      78           0 :   u16 udp_src = IPSEC_UDP_PORT_NONE, udp_dst = IPSEC_UDP_PORT_NONE;
      79           0 :   tunnel_t tun = {};
      80             : 
      81             :   /* SPD policy */
      82           0 :   ipsec_main_t *im = &ipsec_main;
      83           0 :   ipsec_policy_t *p0 = NULL;
      84             :   ipsec_spd_t *spd0;
      85             :   uword *pp;
      86           0 :   u32 stat_index, spd_idx, spd_id = 1;
      87           0 :   int is_add = 1;
      88             :   int rv;
      89           0 :   ipsec_policy_t *p_vec = NULL;
      90             :   u64 i;
      91           0 :   u64 flows = 100;
      92             : 
      93           0 :   u64 t_add_0 = 0;
      94           0 :   u64 t_add_1 = 0;
      95           0 :   u64 t_add = 0;
      96           0 :   u64 t_look_0 = 0;
      97           0 :   u64 t_look_1 = 0;
      98           0 :   u64 t_look = 0;
      99           0 :   u8 flow_cache_enabled = im->output_flow_cache_flag;
     100           0 :   u32 count_cached = 0;
     101           0 :   u32 count_slow_path = 0;
     102           0 :   u32 seed = random_default_seed ();
     103           0 :   u32 *rand_val = NULL;
     104             :   u32 ip4_start;
     105             : #define BURST_MAX_SIZE 256
     106             :   ipsec_policy_t *policies[BURST_MAX_SIZE];
     107             :   ipsec4_spd_5tuple_t ip4_5tuples[BURST_MAX_SIZE];
     108           0 :   u32 burst_size = 10;
     109           0 :   int burst_enabled = 0;
     110           0 :   u64 t0 = clib_cpu_time_now ();
     111           0 :   u64 t1 = 0;
     112           0 :   u32 k = 0, m;
     113           0 :   u64 burst_counter = 0;
     114             : 
     115           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     116             :     {
     117           0 :       if (unformat (input, "flows %d", &flows))
     118             :         ;
     119           0 :       else if (unformat (input, "burst %d", &burst_size))
     120             :         {
     121           0 :           if (burst_size == 0)
     122           0 :             burst_enabled = 0;
     123             :           else
     124             :             {
     125           0 :               burst_enabled = 1;
     126           0 :               burst_size = clib_min (burst_size, BURST_MAX_SIZE);
     127             :             }
     128             :         }
     129             :       else
     130           0 :         break;
     131             :     }
     132             : 
     133           0 :   vlib_cli_output (vm, "Create env:");
     134             :   /* creating a new SA */
     135           0 :   rv = ipsec_sa_add_and_lock (sa_id, spi, proto, crypto_alg, &ck, integ_alg,
     136             :                               &ik, sa_flags, clib_host_to_net_u32 (salt),
     137             :                               udp_src, udp_dst, &tun, &sai);
     138           0 :   if (rv)
     139             :     {
     140           0 :       err = clib_error_return (0, "create sa failure");
     141           0 :       goto done;
     142             :     }
     143             :   else
     144           0 :     vlib_cli_output (vm, "\tAdd a new SA");
     145             : 
     146             :   /* creating a new SPD */
     147           0 :   rv = ipsec_add_del_spd (vm, spd_id, is_add);
     148           0 :   if (rv)
     149             :     {
     150           0 :       err = clib_error_return (0, "create spd failure");
     151           0 :       goto done;
     152             :     }
     153             :   else
     154           0 :     vlib_cli_output (vm, "\tAdd a new SPD");
     155             : 
     156             :   /* vector for spd_policy */
     157           0 :   vec_validate (p_vec, flows + 1);
     158           0 :   vec_validate (rand_val, flows + 1);
     159             : 
     160             :   /* fill spd policy */
     161           0 :   for (i = 0; i < flows; i++)
     162             :     {
     163           0 :       rand_val[i] = random_u32 (&seed) % flows;
     164             : 
     165           0 :       p_vec[i].type = IPSEC_SPD_POLICY_IP4_OUTBOUND;
     166           0 :       p_vec[i].priority = flows - i;
     167           0 :       p_vec[i].policy = IPSEC_POLICY_ACTION_PROTECT;
     168           0 :       p_vec[i].id = spd_id;
     169           0 :       p_vec[i].sa_id = sa_id;
     170           0 :       p_vec[i].protocol = IP_PROTOCOL_UDP;
     171           0 :       p_vec[i].lport.start = 1;
     172           0 :       p_vec[i].lport.stop = 1;
     173           0 :       p_vec[i].rport.start = 1;
     174           0 :       p_vec[i].rport.stop = 1;
     175             :       /* address: 1.0.0.0 as u32 */
     176           0 :       ip4_start = 16777216;
     177           0 :       p_vec[i].laddr.start.ip4.data_u32 =
     178           0 :         clib_host_to_net_u32 (ip4_start + i * 32);
     179           0 :       p_vec[i].laddr.stop.ip4.data_u32 =
     180           0 :         clib_host_to_net_u32 (ip4_start + i * 32);
     181           0 :       p_vec[i].raddr.start.ip4.data_u32 =
     182           0 :         clib_host_to_net_u32 (ip4_start + i * 32);
     183           0 :       p_vec[i].raddr.stop.ip4.data_u32 =
     184           0 :         clib_host_to_net_u32 (ip4_start + i * 32);
     185             :     }
     186             : 
     187           0 :   vlib_cli_output (vm, "Add SPD Policy");
     188           0 :   t_add_0 = clib_cpu_time_now ();
     189           0 :   for (i = 0; i < flows; i++)
     190             :     {
     191           0 :       rv = ipsec_add_del_policy (vm, &p_vec[i], is_add, &stat_index);
     192           0 :       if (rv)
     193             :         {
     194           0 :           clib_warning ("No add SPD Policy: %u", stat_index);
     195           0 :           err = clib_error_return (0, "add SPD Policy failure");
     196           0 :           goto done;
     197             :         }
     198             :     }
     199           0 :   t_add_1 = clib_cpu_time_now ();
     200             : 
     201           0 :   pp = hash_get (im->spd_index_by_spd_id, spd_id);
     202           0 :   spd_idx = pp[0];
     203           0 :   spd0 = pool_elt_at_index (im->spds, spd_idx);
     204             : 
     205           0 :   vlib_cli_output (vm, "Lookup SPD Policy");
     206           0 :   u64 j = 0;
     207           0 :   u64 n_lookup = 1000 * 1000;
     208           0 :   t_look_0 = clib_cpu_time_now ();
     209           0 :   for (i = 0; i < n_lookup; i++)
     210             :     {
     211           0 :       if (flows == j)
     212           0 :         j = 0;
     213             : 
     214           0 :       p0 = NULL;
     215           0 :       if (flow_cache_enabled)
     216             :         {
     217           0 :           p0 = ipsec4_out_spd_find_flow_cache_entry (
     218             :             im, 0,
     219             :             clib_net_to_host_u32 (ip4_start +
     220           0 :                                   ((flows - 1) - rand_val[j]) * 32),
     221             :             clib_net_to_host_u32 (ip4_start +
     222           0 :                                   ((flows - 1) - rand_val[j]) * 32),
     223           0 :             clib_net_to_host_u16 (1), clib_net_to_host_u16 (1));
     224           0 :           if (p0)
     225           0 :             count_cached++;
     226             :         }
     227           0 :       if (p0 == NULL)
     228             :         {
     229           0 :           if (burst_enabled)
     230             :             {
     231           0 :               u32 src_addr = (ip4_start + ((flows - 1) - rand_val[j]) * 32);
     232           0 :               u32 dst_addr = (ip4_start + ((flows - 1) - rand_val[j]) * 32);
     233           0 :               ipsec4_spd_5tuple_t ip4_5tuple = {
     234             :                 .ip4_addr = { (ip4_address_t) src_addr,
     235             :                               (ip4_address_t) dst_addr },
     236             :                 .port = { 1, 1 },
     237             :                 .proto = IP_PROTOCOL_UDP
     238             :               };
     239             : 
     240           0 :               if (k == burst_size)
     241             :                 {
     242           0 :                   k = 0;
     243           0 :                   clib_memset (policies, 0,
     244             :                                burst_size * sizeof (ipsec_policy_t *));
     245           0 :                   burst_counter += ipsec_output_policy_match_n (
     246             :                     spd0, ip4_5tuples, policies, burst_size,
     247             :                     flow_cache_enabled);
     248           0 :                   for (m = 0; m < burst_size; m++)
     249             :                     {
     250           0 :                       ASSERT (policies[m] != 0);
     251             :                     }
     252             :                 }
     253             : 
     254           0 :               clib_memcpy (ip4_5tuples + k, &ip4_5tuple,
     255             :                            sizeof (ipsec4_spd_5tuple_t));
     256           0 :               k++;
     257             :             }
     258             :           else
     259             :             {
     260             : 
     261           0 :               p0 = ipsec_output_policy_match (
     262             :                 spd0, IP_PROTOCOL_UDP,
     263           0 :                 (ip4_start + ((flows - 1) - rand_val[j]) * 32),
     264           0 :                 (ip4_start + ((flows - 1) - rand_val[j]) * 32), 1, 1,
     265             :                 flow_cache_enabled);
     266             :             }
     267             : 
     268           0 :           count_slow_path++;
     269             :         }
     270           0 :       j++;
     271           0 :       if (!burst_enabled)
     272           0 :         ASSERT (p0 != 0);
     273             :     }
     274             : 
     275           0 :   if (burst_enabled && k > 0)
     276             :     {
     277           0 :       clib_memset (policies, 0, k * sizeof (ipsec_policy_t *));
     278           0 :       burst_counter += ipsec_output_policy_match_n (
     279             :         spd0, ip4_5tuples, policies, k, flow_cache_enabled);
     280           0 :       for (m = 0; m < k; m++)
     281             :         {
     282           0 :           ASSERT (policies[m] != 0);
     283             :         }
     284             :     }
     285           0 :   t_look_1 = clib_cpu_time_now ();
     286             : 
     287           0 :   t_add = (t_add_1 - t_add_0);
     288           0 :   t_look = (t_look_1 - t_look_0);
     289             : 
     290           0 :   vlib_cli_output (vm, "Results Outbound:");
     291           0 :   vlib_cli_output (vm, "Time to add %u flows: \t\t%12.10f s", flows,
     292           0 :                    (t_add / vm->clib_time.clocks_per_second));
     293           0 :   vlib_cli_output (vm, "Average time to add 1 flow: \t\t%12.10f s",
     294           0 :                    ((t_add / flows) / vm->clib_time.clocks_per_second));
     295           0 :   vlib_cli_output (vm, "Time to lookup %u flows: \t\t%12.10f s", flows,
     296           0 :                    (t_look / vm->clib_time.clocks_per_second));
     297           0 :   vlib_cli_output (vm, "Average time to lookup 1 flow: \t\t%12.10f s",
     298           0 :                    ((t_look / n_lookup) / vm->clib_time.clocks_per_second));
     299             : 
     300           0 :   vlib_cli_output (vm, " ");
     301             : 
     302           0 :   vlib_cli_output (vm, "Cycle CPU to add %u flows: \t\t%32lu cycles", flows,
     303             :                    t_add);
     304           0 :   vlib_cli_output (vm, "Average cycle CPU to add 1 flow: \t%32lu cycles",
     305             :                    t_add / flows);
     306           0 :   vlib_cli_output (vm, "Cycle CPU to lookup %u flows: \t%32lu cycles", flows,
     307             :                    t_look);
     308           0 :   vlib_cli_output (vm, "Average cycle CPU to lookup 1 flow: \t%32lu cycles",
     309             :                    t_look / n_lookup);
     310             : 
     311           0 :   if (count_slow_path || count_cached)
     312           0 :     vlib_cli_output (
     313             :       vm, "flow cache hit rate: \t\t%12.10f\n cached: \t%d\n slow_path: \t%d",
     314           0 :       ((float) count_cached) / ((float) count_cached + count_slow_path),
     315             :       count_cached, count_slow_path);
     316             : 
     317           0 :   if (burst_enabled)
     318           0 :     vlib_cli_output (vm, "Total number of packets matched in bursts: \t\t%d\n",
     319             :                      burst_counter);
     320             : 
     321           0 : done:
     322           0 :   vlib_cli_output (vm, "Cleaning:");
     323             :   /* delete SPD policy */
     324           0 :   is_add = 0;
     325           0 :   for (i = 0; i < flows; i++)
     326             :     {
     327           0 :       rv = ipsec_add_del_policy (vm, &p_vec[i], is_add, &stat_index);
     328           0 :       if (rv)
     329             :         {
     330           0 :           clib_warning ("No delete SPD Policy: %u", i);
     331           0 :           err = clib_error_return (0, "delete SPD Policy failure");
     332             :         }
     333             :     }
     334           0 :   vlib_cli_output (vm, "\tDelete all SPD Policy");
     335             : 
     336             :   /* delete SPD */
     337           0 :   rv = ipsec_add_del_spd (vm, spd_id, is_add);
     338           0 :   if (rv)
     339             :     {
     340           0 :       err = clib_error_return (0, "delete spd failure");
     341             :     }
     342             :   else
     343           0 :     vlib_cli_output (vm, "\tDelete SPD");
     344             : 
     345             :   /* delete SA */
     346           0 :   rv = ipsec_sa_unlock_id (sa_id);
     347           0 :   if (rv)
     348             :     {
     349           0 :       err = clib_error_return (0, "delete sa failure");
     350             :     }
     351             :   else
     352           0 :     vlib_cli_output (vm, "\tDelete SA");
     353             : 
     354           0 :   t1 = clib_cpu_time_now ();
     355           0 :   vlib_cli_output (vm, "Time for test: \t%12.10f s",
     356           0 :                    ((t1 - t0) / vm->clib_time.clocks_per_second));
     357             : 
     358           0 :   vec_free (p_vec);
     359           0 :   vlib_cli_output (vm, "End");
     360             : 
     361           0 :   return (err);
     362             : }
     363             : 
     364       16239 : VLIB_CLI_COMMAND (test_ipsec_spd_perf_command, static) = {
     365             :   .path = "test ipsec_spd_outbound_perf",
     366             :   .short_help = "test ipsec_spd_outbound_perf flows <n_flows>",
     367             :   .function = test_ipsec_spd_outbound_perf_command_fn,
     368             : };
     369             : 
     370             : /* *INDENT-OFF* */
     371       16239 : VLIB_CLI_COMMAND (test_ipsec_command, static) =
     372             : {
     373             :   .path = "test ipsec",
     374             :   .short_help = "test ipsec sa <ID> seq-num <VALUE>",
     375             :   .function = test_ipsec_command_fn,
     376             : };
     377             : /* *INDENT-ON* */
     378             : 
     379             : /*
     380             :  * fd.io coding-style-patch-verification: ON
     381             :  *
     382             :  * Local Variables:
     383             :  * eval: (c-set-style "gnu")
     384             :  * End:
     385             :  */

Generated by: LCOV version 1.14