LCOV - code coverage report
Current view: top level - vnet/ipsec - ipsec_cli.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 115 430 26.7 %
Date: 2023-07-05 22:20:52 Functions: 52 61 85.2 %

          Line data    Source code
       1             : /*
       2             :  * decap.c : IPSec tunnel support
       3             :  *
       4             :  * Copyright (c) 2015 Cisco and/or its affiliates.
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at:
       8             :  *
       9             :  *     http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : #include <vnet/vnet.h>
      19             : #include <vnet/api_errno.h>
      20             : #include <vnet/ip/ip.h>
      21             : #include <vnet/interface.h>
      22             : #include <vnet/fib/fib.h>
      23             : #include <vnet/ipip/ipip.h>
      24             : 
      25             : #include <vnet/ipsec/ipsec.h>
      26             : #include <vnet/ipsec/ipsec_tun.h>
      27             : 
      28             : static clib_error_t *
      29           0 : set_interface_spd_command_fn (vlib_main_t * vm,
      30             :                               unformat_input_t * input,
      31             :                               vlib_cli_command_t * cmd)
      32             : {
      33           0 :   unformat_input_t _line_input, *line_input = &_line_input;
      34           0 :   ipsec_main_t *im = &ipsec_main;
      35           0 :   u32 sw_if_index = (u32) ~ 0;
      36             :   u32 spd_id;
      37           0 :   int is_add = 1;
      38           0 :   clib_error_t *error = NULL;
      39             :   int err;
      40             : 
      41           0 :   if (!unformat_user (input, unformat_line_input, line_input))
      42           0 :     return 0;
      43             : 
      44           0 :   if (unformat
      45             :       (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main,
      46             :        &sw_if_index, &spd_id))
      47             :     ;
      48           0 :   else if (unformat (line_input, "del"))
      49           0 :     is_add = 0;
      50             :   else
      51             :     {
      52           0 :       error = clib_error_return (0, "parse error: '%U'",
      53             :                                  format_unformat_error, line_input);
      54           0 :       goto done;
      55             :     }
      56             : 
      57           0 :   err = ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add);
      58           0 :   switch (err)
      59             :     {
      60           0 :     case VNET_API_ERROR_SYSCALL_ERROR_1:
      61           0 :       error = clib_error_return (0, "no such spd-id");
      62           0 :       break;
      63           0 :     case VNET_API_ERROR_SYSCALL_ERROR_2:
      64           0 :       error = clib_error_return (0, "spd already assigned");
      65           0 :       break;
      66             :     }
      67             : 
      68           0 : done:
      69           0 :   unformat_free (line_input);
      70             : 
      71           0 :   return error;
      72             : }
      73             : 
      74             : /* *INDENT-OFF* */
      75      272887 : VLIB_CLI_COMMAND (set_interface_spd_command, static) = {
      76             :     .path = "set interface ipsec spd",
      77             :     .short_help =
      78             :     "set interface ipsec spd <int> <id>",
      79             :     .function = set_interface_spd_command_fn,
      80             : };
      81             : /* *INDENT-ON* */
      82             : 
      83             : static clib_error_t *
      84           0 : ipsec_sa_add_del_command_fn (vlib_main_t * vm,
      85             :                              unformat_input_t * input,
      86             :                              vlib_cli_command_t * cmd)
      87             : {
      88           0 :   unformat_input_t _line_input, *line_input = &_line_input;
      89             :   ipsec_crypto_alg_t crypto_alg;
      90             :   ipsec_integ_alg_t integ_alg;
      91             :   ipsec_protocol_t proto;
      92             :   ipsec_sa_flags_t flags;
      93             :   clib_error_t *error;
      94           0 :   ipsec_key_t ck = { 0 };
      95           0 :   ipsec_key_t ik = { 0 };
      96             :   u32 id, spi, salt, sai;
      97           0 :   int i = 0;
      98             :   u16 udp_src, udp_dst;
      99             :   int is_add, rv;
     100           0 :   u32 m_args = 0;
     101           0 :   tunnel_t tun = {};
     102             : 
     103           0 :   salt = 0;
     104           0 :   error = NULL;
     105           0 :   is_add = 0;
     106           0 :   flags = IPSEC_SA_FLAG_NONE;
     107           0 :   proto = IPSEC_PROTOCOL_ESP;
     108           0 :   integ_alg = IPSEC_INTEG_ALG_NONE;
     109           0 :   crypto_alg = IPSEC_CRYPTO_ALG_NONE;
     110           0 :   udp_src = udp_dst = IPSEC_UDP_PORT_NONE;
     111             : 
     112           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     113           0 :     return 0;
     114             : 
     115           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     116             :     {
     117           0 :       if (unformat (line_input, "add %u", &id))
     118             :         {
     119           0 :           is_add = 1;
     120           0 :           m_args |= 1 << 0;
     121             :         }
     122           0 :       else if (unformat (line_input, "del %u", &id))
     123             :         {
     124           0 :           is_add = 0;
     125           0 :           m_args |= 1 << 0;
     126             :         }
     127           0 :       else if (unformat (line_input, "spi %u", &spi))
     128           0 :         m_args |= 1 << 1;
     129           0 :       else if (unformat (line_input, "salt 0x%x", &salt))
     130             :         ;
     131           0 :       else if (unformat (line_input, "esp"))
     132           0 :         proto = IPSEC_PROTOCOL_ESP;
     133           0 :       else if (unformat (line_input, "ah"))
     134           0 :         proto = IPSEC_PROTOCOL_AH;
     135           0 :       else if (unformat (line_input, "crypto-key %U",
     136             :                          unformat_ipsec_key, &ck))
     137             :         ;
     138           0 :       else if (unformat (line_input, "crypto-alg %U",
     139             :                          unformat_ipsec_crypto_alg, &crypto_alg))
     140             :         ;
     141           0 :       else if (unformat (line_input, "integ-key %U", unformat_ipsec_key, &ik))
     142             :         ;
     143           0 :       else if (unformat (line_input, "integ-alg %U",
     144             :                          unformat_ipsec_integ_alg, &integ_alg))
     145             :         ;
     146           0 :       else if (unformat (line_input, "%U", unformat_tunnel, &tun))
     147             :         {
     148           0 :           flags |= IPSEC_SA_FLAG_IS_TUNNEL;
     149           0 :           if (AF_IP6 == tunnel_get_af (&tun))
     150           0 :             flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
     151             :         }
     152           0 :       else if (unformat (line_input, "udp-src-port %d", &i))
     153           0 :         udp_src = i;
     154           0 :       else if (unformat (line_input, "udp-dst-port %d", &i))
     155           0 :         udp_dst = i;
     156           0 :       else if (unformat (line_input, "inbound"))
     157           0 :         flags |= IPSEC_SA_FLAG_IS_INBOUND;
     158           0 :       else if (unformat (line_input, "use-anti-replay"))
     159           0 :         flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
     160           0 :       else if (unformat (line_input, "use-esn"))
     161           0 :         flags |= IPSEC_SA_FLAG_USE_ESN;
     162           0 :       else if (unformat (line_input, "udp-encap"))
     163           0 :         flags |= IPSEC_SA_FLAG_UDP_ENCAP;
     164           0 :       else if (unformat (line_input, "async"))
     165           0 :         flags |= IPSEC_SA_FLAG_IS_ASYNC;
     166             :       else
     167             :         {
     168           0 :           error = clib_error_return (0, "parse error: '%U'",
     169             :                                      format_unformat_error, line_input);
     170           0 :           goto done;
     171             :         }
     172             :     }
     173             : 
     174           0 :   if (!(m_args & 1))
     175             :     {
     176           0 :       error = clib_error_return (0, "missing id");
     177           0 :       goto done;
     178             :     }
     179             : 
     180           0 :   if (is_add)
     181             :     {
     182           0 :       if (!(m_args & 2))
     183             :         {
     184           0 :           error = clib_error_return (0, "missing spi");
     185           0 :           goto done;
     186             :         }
     187           0 :       rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, &ck, integ_alg,
     188             :                                   &ik, flags, clib_host_to_net_u32 (salt),
     189             :                                   udp_src, udp_dst, &tun, &sai);
     190             :     }
     191             :   else
     192             :     {
     193           0 :       rv = ipsec_sa_unlock_id (id);
     194             :     }
     195             : 
     196           0 :   if (rv)
     197           0 :     error = clib_error_return (0, "failed: %d", rv);
     198             : 
     199           0 : done:
     200           0 :   unformat_free (line_input);
     201             : 
     202           0 :   return error;
     203             : }
     204             : 
     205             : /* *INDENT-OFF* */
     206      272887 : VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = {
     207             :     .path = "ipsec sa",
     208             :     .short_help =
     209             :     "ipsec sa [add|del]",
     210             :     .function = ipsec_sa_add_del_command_fn,
     211             : };
     212             : /* *INDENT-ON* */
     213             : 
     214             : static clib_error_t *
     215           0 : ipsec_sa_bind_cli (vlib_main_t *vm, unformat_input_t *input,
     216             :                    vlib_cli_command_t *cmd)
     217             : {
     218           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     219           0 :   u32 id = ~0;
     220           0 :   u32 worker = ~0;
     221           0 :   bool bind = 1;
     222             :   int rv;
     223           0 :   clib_error_t *error = NULL;
     224             : 
     225           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     226           0 :     return 0;
     227             : 
     228           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     229             :     {
     230           0 :       if (unformat (line_input, "unbind"))
     231           0 :         bind = 0;
     232           0 :       else if (id != ~0 && unformat (line_input, "%u", &id))
     233             :         ;
     234           0 :       else if (unformat (line_input, "%u", &worker))
     235             :         ;
     236             :       else
     237             :         {
     238           0 :           error = clib_error_return (0, "parse error: '%U'",
     239             :                                      format_unformat_error, line_input);
     240           0 :           goto done;
     241             :         }
     242             :     }
     243             : 
     244           0 :   if (id == ~0)
     245             :     {
     246           0 :       error = clib_error_return (0, "please specify SA ID");
     247           0 :       goto done;
     248             :     }
     249             : 
     250           0 :   if (bind && ~0 == worker)
     251             :     {
     252           0 :       error = clib_error_return (0, "please specify worker to bind to");
     253           0 :       goto done;
     254             :     }
     255             : 
     256           0 :   rv = ipsec_sa_bind (id, worker, bind);
     257           0 :   switch (rv)
     258             :     {
     259           0 :     case VNET_API_ERROR_INVALID_VALUE:
     260           0 :       error = clib_error_return (0, "please specify a valid SA ID");
     261           0 :       break;
     262           0 :     case VNET_API_ERROR_INVALID_WORKER:
     263           0 :       error = clib_error_return (0, "please specify a valid worker index");
     264           0 :       break;
     265             :     }
     266             : 
     267           0 : done:
     268           0 :   unformat_free (line_input);
     269             : 
     270           0 :   return error;
     271             : }
     272             : 
     273      272887 : VLIB_CLI_COMMAND (ipsec_sa_bind_cmd, static) = {
     274             :   .path = "ipsec sa bind",
     275             :   .short_help = "ipsec sa [unbind] <sa-id> <worker>",
     276             :   .function = ipsec_sa_bind_cli,
     277             : };
     278             : 
     279             : static clib_error_t *
     280           0 : ipsec_spd_add_del_command_fn (vlib_main_t * vm,
     281             :                               unformat_input_t * input,
     282             :                               vlib_cli_command_t * cmd)
     283             : {
     284           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     285           0 :   u32 spd_id = ~0;
     286           0 :   int is_add = ~0;
     287           0 :   clib_error_t *error = NULL;
     288             : 
     289           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     290           0 :     return 0;
     291             : 
     292           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     293             :     {
     294           0 :       if (unformat (line_input, "add"))
     295           0 :         is_add = 1;
     296           0 :       else if (unformat (line_input, "del"))
     297           0 :         is_add = 0;
     298           0 :       else if (unformat (line_input, "%u", &spd_id))
     299             :         ;
     300             :       else
     301             :         {
     302           0 :           error = clib_error_return (0, "parse error: '%U'",
     303             :                                      format_unformat_error, line_input);
     304           0 :           goto done;
     305             :         }
     306             :     }
     307             : 
     308           0 :   if (spd_id == ~0)
     309             :     {
     310           0 :       error = clib_error_return (0, "please specify SPD ID");
     311           0 :       goto done;
     312             :     }
     313             : 
     314           0 :   ipsec_add_del_spd (vm, spd_id, is_add);
     315             : 
     316           0 : done:
     317           0 :   unformat_free (line_input);
     318             : 
     319           0 :   return error;
     320             : }
     321             : 
     322             : /* *INDENT-OFF* */
     323      272887 : VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = {
     324             :     .path = "ipsec spd",
     325             :     .short_help =
     326             :     "ipsec spd [add|del] <id>",
     327             :     .function = ipsec_spd_add_del_command_fn,
     328             : };
     329             : /* *INDENT-ON* */
     330             : 
     331             : 
     332             : static clib_error_t *
     333           0 : ipsec_policy_add_del_command_fn (vlib_main_t * vm,
     334             :                                  unformat_input_t * input,
     335             :                                  vlib_cli_command_t * cmd)
     336             : {
     337           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     338             :   ipsec_policy_t p;
     339           0 :   int rv, is_add = 0;
     340             :   u32 tmp, tmp2, stat_index, local_range_set, remote_range_set;
     341           0 :   clib_error_t *error = NULL;
     342             :   u32 is_outbound;
     343             : 
     344           0 :   clib_memset (&p, 0, sizeof (p));
     345           0 :   p.lport.stop = p.rport.stop = ~0;
     346           0 :   remote_range_set = local_range_set = is_outbound = 0;
     347           0 :   p.protocol = IPSEC_POLICY_PROTOCOL_ANY;
     348             : 
     349           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     350           0 :     return 0;
     351             : 
     352           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     353             :     {
     354           0 :       if (unformat (line_input, "add"))
     355           0 :         is_add = 1;
     356           0 :       else if (unformat (line_input, "del"))
     357           0 :         is_add = 0;
     358           0 :       else if (unformat (line_input, "ip6"))
     359           0 :         p.is_ipv6 = 1;
     360           0 :       else if (unformat (line_input, "spd %u", &p.id))
     361             :         ;
     362           0 :       else if (unformat (line_input, "inbound"))
     363           0 :         is_outbound = 0;
     364           0 :       else if (unformat (line_input, "outbound"))
     365           0 :         is_outbound = 1;
     366           0 :       else if (unformat (line_input, "priority %d", &p.priority))
     367             :         ;
     368           0 :       else if (unformat (line_input, "protocol %u", &tmp))
     369           0 :         p.protocol = (u8) tmp;
     370             :       else
     371           0 :         if (unformat
     372             :             (line_input, "action %U", unformat_ipsec_policy_action,
     373             :              &p.policy))
     374             :         {
     375           0 :           if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
     376             :             {
     377           0 :               error = clib_error_return (0, "unsupported action: 'resolve'");
     378           0 :               goto done;
     379             :             }
     380             :         }
     381           0 :       else if (unformat (line_input, "sa %u", &p.sa_id))
     382             :         ;
     383           0 :       else if (unformat (line_input, "local-ip-range %U - %U",
     384             :                          unformat_ip4_address, &p.laddr.start.ip4,
     385             :                          unformat_ip4_address, &p.laddr.stop.ip4))
     386           0 :         local_range_set = 1;
     387           0 :       else if (unformat (line_input, "remote-ip-range %U - %U",
     388             :                          unformat_ip4_address, &p.raddr.start.ip4,
     389             :                          unformat_ip4_address, &p.raddr.stop.ip4))
     390           0 :         remote_range_set = 1;
     391           0 :       else if (unformat (line_input, "local-ip-range %U - %U",
     392             :                          unformat_ip6_address, &p.laddr.start.ip6,
     393             :                          unformat_ip6_address, &p.laddr.stop.ip6))
     394             :         {
     395           0 :           p.is_ipv6 = 1;
     396           0 :           local_range_set = 1;
     397             :         }
     398           0 :       else if (unformat (line_input, "remote-ip-range %U - %U",
     399             :                          unformat_ip6_address, &p.raddr.start.ip6,
     400             :                          unformat_ip6_address, &p.raddr.stop.ip6))
     401             :         {
     402           0 :           p.is_ipv6 = 1;
     403           0 :           remote_range_set = 1;
     404             :         }
     405           0 :       else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2))
     406             :         {
     407           0 :           p.lport.start = tmp;
     408           0 :           p.lport.stop = tmp2;
     409             :         }
     410             :       else
     411           0 :         if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2))
     412             :         {
     413           0 :           p.rport.start = tmp;
     414           0 :           p.rport.stop = tmp2;
     415             :         }
     416             :       else
     417             :         {
     418           0 :           error = clib_error_return (0, "parse error: '%U'",
     419             :                                      format_unformat_error, line_input);
     420           0 :           goto done;
     421             :         }
     422             :     }
     423             : 
     424           0 :   if (!remote_range_set)
     425             :     {
     426           0 :       if (p.is_ipv6)
     427           0 :         clib_memset (&p.raddr.stop.ip6, 0xff, 16);
     428             :       else
     429           0 :         clib_memset (&p.raddr.stop.ip4, 0xff, 4);
     430             :     }
     431           0 :   if (!local_range_set)
     432             :     {
     433           0 :       if (p.is_ipv6)
     434           0 :         clib_memset (&p.laddr.stop.ip6, 0xff, 16);
     435             :       else
     436           0 :         clib_memset (&p.laddr.stop.ip4, 0xff, 4);
     437             :     }
     438             : 
     439           0 :   rv = ipsec_policy_mk_type (is_outbound, p.is_ipv6, p.policy, &p.type);
     440             : 
     441           0 :   if (rv)
     442             :     {
     443           0 :       error = clib_error_return (0, "unsupported policy type for:",
     444             :                                  " outboud:%s %s action:%U",
     445             :                                  (is_outbound ? "yes" : "no"),
     446             :                                  (p.is_ipv6 ? "IPv4" : "IPv6"),
     447             :                                  format_ipsec_policy_action, p.policy);
     448           0 :       goto done;
     449             :     }
     450             : 
     451           0 :   rv = ipsec_add_del_policy (vm, &p, is_add, &stat_index);
     452             : 
     453           0 :   if (!rv)
     454           0 :     vlib_cli_output (vm, "policy-index:%d", stat_index);
     455             :   else
     456           0 :     vlib_cli_output (vm, "error:%d", rv);
     457             : 
     458           0 : done:
     459           0 :   unformat_free (line_input);
     460             : 
     461           0 :   return error;
     462             : }
     463             : 
     464             : /* *INDENT-OFF* */
     465      272887 : VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = {
     466             :     .path = "ipsec policy",
     467             :     .short_help =
     468             :     "ipsec policy [add|del] spd <id> priority <n> ",
     469             :     .function = ipsec_policy_add_del_command_fn,
     470             : };
     471             : /* *INDENT-ON* */
     472             : 
     473             : static void
     474        3326 : ipsec_sa_show_all (vlib_main_t * vm, ipsec_main_t * im, u8 detail)
     475             : {
     476             :   u32 sai;
     477             : 
     478             :   /* *INDENT-OFF* */
     479       31008 :   pool_foreach_index (sai, ipsec_sa_pool)
     480             :     {
     481       27682 :       vlib_cli_output (vm, "%U", format_ipsec_sa, sai,
     482             :                        (detail ? IPSEC_FORMAT_DETAIL : IPSEC_FORMAT_BRIEF));
     483             :     }
     484             :   /* *INDENT-ON* */
     485        3326 : }
     486             : 
     487             : static void
     488        3347 : ipsec_spd_show_all (vlib_main_t * vm, ipsec_main_t * im)
     489             : {
     490             :   u32 spdi;
     491             : 
     492             :   /* *INDENT-OFF* */
     493        9373 :   pool_foreach_index (spdi, im->spds)  {
     494        6026 :     vlib_cli_output(vm, "%U", format_ipsec_spd, spdi);
     495             :   }
     496             : 
     497        3347 :   if (im->output_flow_cache_flag)
     498             :     {
     499          47 :       vlib_cli_output (vm, "%U", format_ipsec_out_spd_flow_cache);
     500             :     }
     501        3347 :   if (im->input_flow_cache_flag)
     502             :     {
     503          51 :       vlib_cli_output (vm, "%U", format_ipsec_in_spd_flow_cache);
     504             :     }
     505             :   /* *INDENT-ON* */
     506        3347 : }
     507             : 
     508             : static void
     509        3303 : ipsec_spd_bindings_show_all (vlib_main_t * vm, ipsec_main_t * im)
     510             : {
     511             :   u32 spd_id, sw_if_index;
     512             :   ipsec_spd_t *spd;
     513             : 
     514        3303 :   vlib_cli_output (vm, "SPD Bindings:");
     515             : 
     516             :   /* *INDENT-OFF* */
     517      220823 :   hash_foreach(sw_if_index, spd_id, im->spd_index_by_sw_if_index, ({
     518             :     spd = pool_elt_at_index (im->spds, spd_id);
     519             :     vlib_cli_output (vm, "  %d -> %U", spd->id,
     520             :                      format_vnet_sw_if_index_name, im->vnet_main,
     521             :                      sw_if_index);
     522             :   }));
     523             :   /* *INDENT-ON* */
     524        3303 : }
     525             : 
     526             : static walk_rc_t
     527        2106 : ipsec_tun_protect_show_one (index_t itpi, void *ctx)
     528             : {
     529        2106 :   vlib_cli_output (ctx, "%U", format_ipsec_tun_protect_index, itpi);
     530             : 
     531        2106 :   return (WALK_CONTINUE);
     532             : }
     533             : 
     534             : static void
     535           3 : ipsec_tunnel_show_all (vlib_main_t * vm)
     536             : {
     537           3 :   ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
     538           3 : }
     539             : 
     540             : static clib_error_t *
     541        3303 : show_ipsec_command_fn (vlib_main_t * vm,
     542             :                        unformat_input_t * input, vlib_cli_command_t * cmd)
     543             : {
     544        3303 :   ipsec_main_t *im = &ipsec_main;
     545             : 
     546        3303 :   ipsec_sa_show_all (vm, im, 0);
     547        3303 :   ipsec_spd_show_all (vm, im);
     548        3303 :   ipsec_spd_bindings_show_all (vm, im);
     549        3303 :   ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
     550             : 
     551        3303 :   vlib_cli_output (vm, "IPSec async mode: %s",
     552        3303 :                    (im->async_mode ? "on" : "off"));
     553             : 
     554        3303 :   return 0;
     555             : }
     556             : 
     557             : /* *INDENT-OFF* */
     558      272887 : VLIB_CLI_COMMAND (show_ipsec_command, static) = {
     559             :     .path = "show ipsec all",
     560             :     .short_help = "show ipsec all",
     561             :     .function = show_ipsec_command_fn,
     562             : };
     563             : /* *INDENT-ON* */
     564             : 
     565             : static clib_error_t *
     566        1392 : show_ipsec_sa_command_fn (vlib_main_t * vm,
     567             :                           unformat_input_t * input, vlib_cli_command_t * cmd)
     568             : {
     569        1392 :   ipsec_main_t *im = &ipsec_main;
     570        1392 :   u32 sai = ~0;
     571        1392 :   u8 detail = 0;
     572             : 
     573        1392 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     574             :     {
     575        1369 :       if (unformat (input, "%u", &sai))
     576             :         ;
     577        1369 :       if (unformat (input, "detail"))
     578           0 :         detail = 1;
     579             :       else
     580        1369 :         break;
     581             :     }
     582             : 
     583        1392 :   if (~0 == sai)
     584          23 :     ipsec_sa_show_all (vm, im, detail);
     585             :   else
     586        1369 :     vlib_cli_output (vm, "%U", format_ipsec_sa, sai,
     587             :                      IPSEC_FORMAT_DETAIL | IPSEC_FORMAT_INSECURE);
     588             : 
     589        1392 :   return 0;
     590             : }
     591             : 
     592             : static clib_error_t *
     593        2378 : clear_ipsec_sa_command_fn (vlib_main_t * vm,
     594             :                            unformat_input_t * input, vlib_cli_command_t * cmd)
     595             : {
     596        2378 :   u32 sai = ~0;
     597             : 
     598        2378 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     599             :     {
     600           0 :       if (unformat (input, "%u", &sai))
     601             :         ;
     602             :       else
     603           0 :         break;
     604             :     }
     605             : 
     606        2378 :   if (~0 == sai)
     607             :     {
     608             :       /* *INDENT-OFF* */
     609       23196 :       pool_foreach_index (sai, ipsec_sa_pool)
     610             :         {
     611       20818 :           ipsec_sa_clear (sai);
     612             :         }
     613             :       /* *INDENT-ON* */
     614             :     }
     615             :   else
     616             :     {
     617           0 :       if (pool_is_free_index (ipsec_sa_pool, sai))
     618           0 :         return clib_error_return (0, "unknown SA index: %d", sai);
     619             :       else
     620           0 :         ipsec_sa_clear (sai);
     621             :     }
     622             : 
     623        2378 :   return 0;
     624             : }
     625             : 
     626             : /* *INDENT-OFF* */
     627      272887 : VLIB_CLI_COMMAND (show_ipsec_sa_command, static) = {
     628             :     .path = "show ipsec sa",
     629             :     .short_help = "show ipsec sa [index]",
     630             :     .function = show_ipsec_sa_command_fn,
     631             : };
     632             : 
     633      272887 : VLIB_CLI_COMMAND (clear_ipsec_sa_command, static) = {
     634             :     .path = "clear ipsec sa",
     635             :     .short_help = "clear ipsec sa [index]",
     636             :     .function = clear_ipsec_sa_command_fn,
     637             : };
     638             : /* *INDENT-ON* */
     639             : 
     640             : static clib_error_t *
     641          44 : show_ipsec_spd_command_fn (vlib_main_t * vm,
     642             :                            unformat_input_t * input, vlib_cli_command_t * cmd)
     643             : {
     644          44 :   ipsec_main_t *im = &ipsec_main;
     645          44 :   u8 show_bindings = 0;
     646          44 :   u32 spdi = ~0;
     647             : 
     648          44 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     649             :     {
     650           0 :       if (unformat (input, "%u", &spdi))
     651             :         ;
     652           0 :       else if (unformat (input, "bindings"))
     653           0 :         show_bindings = 1;
     654             :       else
     655           0 :         break;
     656             :     }
     657             : 
     658          44 :   if (show_bindings)
     659           0 :     ipsec_spd_bindings_show_all (vm, im);
     660          44 :   else if (~0 != spdi)
     661           0 :     vlib_cli_output (vm, "%U", format_ipsec_spd, spdi);
     662             :   else
     663          44 :     ipsec_spd_show_all (vm, im);
     664             : 
     665          44 :   return 0;
     666             : }
     667             : 
     668             : /* *INDENT-OFF* */
     669      272887 : VLIB_CLI_COMMAND (show_ipsec_spd_command, static) = {
     670             :     .path = "show ipsec spd",
     671             :     .short_help = "show ipsec spd [index]",
     672             :     .function = show_ipsec_spd_command_fn,
     673             : };
     674             : /* *INDENT-ON* */
     675             : 
     676             : static clib_error_t *
     677           3 : show_ipsec_tunnel_command_fn (vlib_main_t * vm,
     678             :                               unformat_input_t * input,
     679             :                               vlib_cli_command_t * cmd)
     680             : {
     681           3 :   ipsec_tunnel_show_all (vm);
     682             : 
     683           3 :   return 0;
     684             : }
     685             : 
     686             : /* *INDENT-OFF* */
     687      272887 : VLIB_CLI_COMMAND (show_ipsec_tunnel_command, static) = {
     688             :     .path = "show ipsec tunnel",
     689             :     .short_help = "show ipsec tunnel",
     690             :     .function = show_ipsec_tunnel_command_fn,
     691             : };
     692             : /* *INDENT-ON* */
     693             : 
     694             : static clib_error_t *
     695           0 : ipsec_show_backends_command_fn (vlib_main_t * vm,
     696             :                                 unformat_input_t * input,
     697             :                                 vlib_cli_command_t * cmd)
     698             : {
     699           0 :   ipsec_main_t *im = &ipsec_main;
     700           0 :   u32 verbose = 0;
     701             : 
     702           0 :   (void) unformat (input, "verbose %u", &verbose);
     703             : 
     704           0 :   vlib_cli_output (vm, "IPsec AH backends available:");
     705           0 :   u8 *s = format (NULL, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
     706             :   ipsec_ah_backend_t *ab;
     707             :   /* *INDENT-OFF* */
     708           0 :   pool_foreach (ab, im->ah_backends) {
     709           0 :     s = format (s, "%=25s %=25u %=10s\n", ab->name, ab - im->ah_backends,
     710           0 :                 ab - im->ah_backends == im->ah_current_backend ? "yes" : "no");
     711           0 :     if (verbose) {
     712             :         vlib_node_t *n;
     713           0 :         n = vlib_get_node (vm, ab->ah4_encrypt_node_index);
     714           0 :         s = format (s, "     enc4 %s (next %d)\n", n->name, ab->ah4_encrypt_next_index);
     715           0 :         n = vlib_get_node (vm, ab->ah4_decrypt_node_index);
     716           0 :         s = format (s, "     dec4 %s (next %d)\n", n->name, ab->ah4_decrypt_next_index);
     717           0 :         n = vlib_get_node (vm, ab->ah6_encrypt_node_index);
     718           0 :         s = format (s, "     enc6 %s (next %d)\n", n->name, ab->ah6_encrypt_next_index);
     719           0 :         n = vlib_get_node (vm, ab->ah6_decrypt_node_index);
     720           0 :         s = format (s, "     dec6 %s (next %d)\n", n->name, ab->ah6_decrypt_next_index);
     721             :     }
     722             :   }
     723             :   /* *INDENT-ON* */
     724           0 :   vlib_cli_output (vm, "%v", s);
     725           0 :   vec_set_len (s, 0);
     726           0 :   vlib_cli_output (vm, "IPsec ESP backends available:");
     727           0 :   s = format (s, "%=25s %=25s %=10s\n", "Name", "Index", "Active");
     728             :   ipsec_esp_backend_t *eb;
     729             :   /* *INDENT-OFF* */
     730           0 :   pool_foreach (eb, im->esp_backends) {
     731           0 :     s = format (s, "%=25s %=25u %=10s\n", eb->name, eb - im->esp_backends,
     732           0 :                 eb - im->esp_backends == im->esp_current_backend ? "yes"
     733             :                                                                  : "no");
     734           0 :     if (verbose) {
     735             :         vlib_node_t *n;
     736           0 :         n = vlib_get_node (vm, eb->esp4_encrypt_node_index);
     737           0 :         s = format (s, "     enc4 %s (next %d)\n", n->name, eb->esp4_encrypt_next_index);
     738           0 :         n = vlib_get_node (vm, eb->esp4_decrypt_node_index);
     739           0 :         s = format (s, "     dec4 %s (next %d)\n", n->name, eb->esp4_decrypt_next_index);
     740           0 :         n = vlib_get_node (vm, eb->esp6_encrypt_node_index);
     741           0 :         s = format (s, "     enc6 %s (next %d)\n", n->name, eb->esp6_encrypt_next_index);
     742           0 :         n = vlib_get_node (vm, eb->esp6_decrypt_node_index);
     743           0 :         s = format (s, "     dec6 %s (next %d)\n", n->name, eb->esp6_decrypt_next_index);
     744             :     }
     745             :   }
     746             :   /* *INDENT-ON* */
     747           0 :   vlib_cli_output (vm, "%v", s);
     748             : 
     749           0 :   vec_free (s);
     750           0 :   return 0;
     751             : }
     752             : 
     753             : /* *INDENT-OFF* */
     754      272887 : VLIB_CLI_COMMAND (ipsec_show_backends_command, static) = {
     755             :     .path = "show ipsec backends",
     756             :     .short_help = "show ipsec backends",
     757             :     .function = ipsec_show_backends_command_fn,
     758             : };
     759             : /* *INDENT-ON* */
     760             : 
     761             : static clib_error_t *
     762           0 : ipsec_select_backend_command_fn (vlib_main_t * vm,
     763             :                                  unformat_input_t * input,
     764             :                                  vlib_cli_command_t * cmd)
     765             : {
     766           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     767           0 :   ipsec_main_t *im = &ipsec_main;
     768             :   clib_error_t *error;
     769             :   u32 backend_index;
     770             : 
     771           0 :   error = ipsec_rsc_in_use (im);
     772             : 
     773           0 :   if (error)
     774           0 :     return error;
     775             : 
     776             :   /* Get a line of input. */
     777           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     778           0 :     return 0;
     779             : 
     780           0 :   if (unformat (line_input, "ah"))
     781             :     {
     782           0 :       if (unformat (line_input, "%u", &backend_index))
     783             :         {
     784           0 :           if (ipsec_select_ah_backend (im, backend_index) < 0)
     785             :             {
     786           0 :               return clib_error_return (0, "Invalid AH backend index `%u'",
     787             :                                         backend_index);
     788             :             }
     789             :         }
     790             :       else
     791             :         {
     792           0 :           return clib_error_return (0, "Invalid backend index `%U'",
     793             :                                     format_unformat_error, line_input);
     794             :         }
     795             :     }
     796           0 :   else if (unformat (line_input, "esp"))
     797             :     {
     798           0 :       if (unformat (line_input, "%u", &backend_index))
     799             :         {
     800           0 :           if (ipsec_select_esp_backend (im, backend_index) < 0)
     801             :             {
     802           0 :               return clib_error_return (0, "Invalid ESP backend index `%u'",
     803             :                                         backend_index);
     804             :             }
     805             :         }
     806             :       else
     807             :         {
     808           0 :           return clib_error_return (0, "Invalid backend index `%U'",
     809             :                                     format_unformat_error, line_input);
     810             :         }
     811             :     }
     812             :   else
     813             :     {
     814           0 :       return clib_error_return (0, "Unknown input `%U'",
     815             :                                 format_unformat_error, line_input);
     816             :     }
     817             : 
     818           0 :   return 0;
     819             : }
     820             : 
     821             : /* *INDENT-OFF* */
     822      272887 : VLIB_CLI_COMMAND (ipsec_select_backend_command, static) = {
     823             :     .path = "ipsec select backend",
     824             :     .short_help = "ipsec select backend <ah|esp> <backend index>",
     825             :     .function = ipsec_select_backend_command_fn,
     826             : };
     827             : 
     828             : /* *INDENT-ON* */
     829             : 
     830             : static clib_error_t *
     831         604 : clear_ipsec_counters_command_fn (vlib_main_t * vm,
     832             :                                  unformat_input_t * input,
     833             :                                  vlib_cli_command_t * cmd)
     834             : {
     835         604 :   vlib_clear_combined_counters (&ipsec_spd_policy_counters);
     836         604 :   vlib_clear_combined_counters (&ipsec_sa_counters);
     837       10268 :   for (int i = 0; i < IPSEC_SA_N_ERRORS; i++)
     838        9664 :     vlib_clear_simple_counters (&ipsec_sa_err_counters[i]);
     839             : 
     840         604 :   return (NULL);
     841             : }
     842             : 
     843             : /* *INDENT-OFF* */
     844      272887 : VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = {
     845             :     .path = "clear ipsec counters",
     846             :     .short_help = "clear ipsec counters",
     847             :     .function = clear_ipsec_counters_command_fn,
     848             : };
     849             : /* *INDENT-ON* */
     850             : 
     851             : static clib_error_t *
     852           0 : ipsec_tun_protect_cmd (vlib_main_t * vm,
     853             :                        unformat_input_t * input, vlib_cli_command_t * cmd)
     854             : {
     855           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     856           0 :   u32 sw_if_index, is_del, sa_in, sa_out, *sa_ins = NULL;
     857           0 :   ip_address_t peer = { };
     858             :   vnet_main_t *vnm;
     859             : 
     860           0 :   is_del = 0;
     861           0 :   sw_if_index = ~0;
     862           0 :   vnm = vnet_get_main ();
     863             : 
     864           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     865           0 :     return 0;
     866             : 
     867           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     868             :     {
     869           0 :       if (unformat (line_input, "del"))
     870           0 :         is_del = 1;
     871           0 :       else if (unformat (line_input, "add"))
     872           0 :         is_del = 0;
     873           0 :       else if (unformat (line_input, "sa-in %d", &sa_in))
     874           0 :         vec_add1 (sa_ins, sa_in);
     875           0 :       else if (unformat (line_input, "sa-out %d", &sa_out))
     876             :         ;
     877           0 :       else if (unformat (line_input, "%U",
     878             :                          unformat_vnet_sw_interface, vnm, &sw_if_index))
     879             :         ;
     880           0 :       else if (unformat (line_input, "%U", unformat_ip_address, &peer))
     881             :         ;
     882             :       else
     883           0 :         return (clib_error_return (0, "unknown input '%U'",
     884             :                                    format_unformat_error, line_input));
     885             :     }
     886             : 
     887           0 :   if (!is_del)
     888           0 :     ipsec_tun_protect_update (sw_if_index, &peer, sa_out, sa_ins);
     889             :   else
     890           0 :     ipsec_tun_protect_del (sw_if_index, &peer);
     891             : 
     892           0 :   unformat_free (line_input);
     893           0 :   return NULL;
     894             : }
     895             : 
     896             : /**
     897             :  * Protect tunnel with IPSEC
     898             :  */
     899             : /* *INDENT-OFF* */
     900      272887 : VLIB_CLI_COMMAND (ipsec_tun_protect_cmd_node, static) =
     901             : {
     902             :   .path = "ipsec tunnel protect",
     903             :   .function = ipsec_tun_protect_cmd,
     904             :   .short_help = "ipsec tunnel protect <interface> input-sa <SA> output-sa <SA> [add|del]",
     905             :     // this is not MP safe
     906             : };
     907             : /* *INDENT-ON* */
     908             : 
     909             : 
     910             : static clib_error_t *
     911           0 : ipsec_tun_protect_show (vlib_main_t * vm,
     912             :                         unformat_input_t * input, vlib_cli_command_t * cmd)
     913             : {
     914           0 :   ipsec_tun_protect_walk (ipsec_tun_protect_show_one, vm);
     915             : 
     916           0 :   return NULL;
     917             : }
     918             : 
     919             : /**
     920             :  * show IPSEC tunnel protection
     921             :  */
     922             : /* *INDENT-OFF* */
     923      272887 : VLIB_CLI_COMMAND (ipsec_tun_protect_show_node, static) =
     924             : {
     925             :   .path = "show ipsec protect",
     926             :   .function = ipsec_tun_protect_show,
     927             :   .short_help =  "show ipsec protect",
     928             : };
     929             : /* *INDENT-ON* */
     930             : 
     931             : static int
     932          16 : ipsec_tun_protect4_hash_show_one (clib_bihash_kv_8_16_t * kv, void *arg)
     933             : {
     934          16 :   ipsec4_tunnel_kv_t *ikv = (ipsec4_tunnel_kv_t *) kv;
     935          16 :   vlib_main_t *vm = arg;
     936             : 
     937          16 :   vlib_cli_output (vm, " %U", format_ipsec4_tunnel_kv, ikv);
     938             : 
     939          16 :   return (BIHASH_WALK_CONTINUE);
     940             : }
     941             : 
     942             : static int
     943          16 : ipsec_tun_protect6_hash_show_one (clib_bihash_kv_24_16_t * kv, void *arg)
     944             : {
     945          16 :   ipsec6_tunnel_kv_t *ikv = (ipsec6_tunnel_kv_t *) kv;
     946          16 :   vlib_main_t *vm = arg;
     947             : 
     948          16 :   vlib_cli_output (vm, " %U", format_ipsec6_tunnel_kv, ikv);
     949             : 
     950          16 :   return (BIHASH_WALK_CONTINUE);
     951             : }
     952             : 
     953             : static clib_error_t *
     954           2 : ipsec_tun_protect_hash_show (vlib_main_t * vm,
     955             :                              unformat_input_t * input,
     956             :                              vlib_cli_command_t * cmd)
     957             : {
     958           2 :   ipsec_main_t *im = &ipsec_main;
     959             : 
     960             :   {
     961           2 :     vlib_cli_output (vm, "IPv4:");
     962             : 
     963           2 :     clib_bihash_foreach_key_value_pair_8_16
     964             :       (&im->tun4_protect_by_key, ipsec_tun_protect4_hash_show_one, vm);
     965             : 
     966           2 :     vlib_cli_output (vm, "IPv6:");
     967             : 
     968           2 :     clib_bihash_foreach_key_value_pair_24_16
     969             :       (&im->tun6_protect_by_key, ipsec_tun_protect6_hash_show_one, vm);
     970             :   }
     971             : 
     972           2 :   return NULL;
     973             : }
     974             : 
     975             : /**
     976             :  * show IPSEC tunnel protection hash tables
     977             :  */
     978             : /* *INDENT-OFF* */
     979      272887 : VLIB_CLI_COMMAND (ipsec_tun_protect_hash_show_node, static) =
     980             : {
     981             :   .path = "show ipsec protect-hash",
     982             :   .function = ipsec_tun_protect_hash_show,
     983             :   .short_help =  "show ipsec protect-hash",
     984             : };
     985             : /* *INDENT-ON* */
     986             : 
     987             : clib_error_t *
     988         559 : ipsec_cli_init (vlib_main_t * vm)
     989             : {
     990         559 :   return 0;
     991             : }
     992             : 
     993       51519 : VLIB_INIT_FUNCTION (ipsec_cli_init);
     994             : 
     995             : static clib_error_t *
     996          20 : set_async_mode_command_fn (vlib_main_t * vm, unformat_input_t * input,
     997             :                            vlib_cli_command_t * cmd)
     998             : {
     999          20 :   unformat_input_t _line_input, *line_input = &_line_input;
    1000          20 :   int async_enable = 0;
    1001             : 
    1002          20 :   if (!unformat_user (input, unformat_line_input, line_input))
    1003           0 :     return 0;
    1004             : 
    1005          40 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1006             :     {
    1007          20 :       if (unformat (line_input, "on"))
    1008          20 :         async_enable = 1;
    1009           0 :       else if (unformat (line_input, "off"))
    1010           0 :         async_enable = 0;
    1011             :       else
    1012           0 :         return (clib_error_return (0, "unknown input '%U'",
    1013             :                                    format_unformat_error, line_input));
    1014             :     }
    1015             : 
    1016          20 :   ipsec_set_async_mode (async_enable);
    1017             : 
    1018          20 :   unformat_free (line_input);
    1019          20 :   return (NULL);
    1020             : }
    1021             : 
    1022             : /* *INDENT-OFF* */
    1023      272887 : VLIB_CLI_COMMAND (set_async_mode_command, static) = {
    1024             :     .path = "set ipsec async mode",
    1025             :     .short_help = "set ipsec async mode on|off",
    1026             :     .function = set_async_mode_command_fn,
    1027             : };
    1028             : /* *INDENT-ON* */
    1029             : 
    1030             : /*
    1031             :  * fd.io coding-style-patch-verification: ON
    1032             :  *
    1033             :  * Local Variables:
    1034             :  * eval: (c-set-style "gnu")
    1035             :  * End:
    1036             :  */

Generated by: LCOV version 1.14