LCOV - code coverage report
Current view: top level - vnet/ipip - ipip_cli.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 15 201 7.5 %
Date: 2023-10-26 01:39:38 Functions: 14 20 70.0 %

          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 "ipip.h"
      17             : #include <vppinfra/error.h>
      18             : #include <vnet/vnet.h>
      19             : #include <vnet/fib/fib_table.h>
      20             : 
      21             : static clib_error_t *
      22           0 : create_ipip_tunnel_command_fn (vlib_main_t * vm,
      23             :                                unformat_input_t * input,
      24             :                                vlib_cli_command_t * cmd)
      25             : {
      26           0 :   unformat_input_t _line_input, *line_input = &_line_input;
      27           0 :   ip46_address_t src = ip46_address_initializer, dst =
      28             :     ip46_address_initializer;
      29           0 :   u32 instance = ~0;
      30           0 :   u32 fib_index = 0;
      31           0 :   u32 table_id = 0;
      32             :   int rv;
      33           0 :   u32 num_m_args = 0;
      34             :   u32 sw_if_index;
      35           0 :   clib_error_t *error = NULL;
      36           0 :   bool ip4_set = false, ip6_set = false;
      37           0 :   tunnel_mode_t mode = TUNNEL_MODE_P2P;
      38           0 :   tunnel_encap_decap_flags_t flags = TUNNEL_ENCAP_DECAP_FLAG_NONE;
      39             : 
      40             :   /* Get a line of input. */
      41           0 :   if (!unformat_user (input, unformat_line_input, line_input))
      42           0 :     return 0;
      43             : 
      44           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
      45             :     {
      46           0 :       if (unformat (line_input, "instance %d", &instance))
      47             :         ;
      48             :       else
      49           0 :         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
      50             :         {
      51           0 :           num_m_args++;
      52           0 :           ip4_set = true;
      53             :         }
      54             :       else
      55           0 :         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
      56             :         {
      57           0 :           num_m_args++;
      58           0 :           ip4_set = true;
      59             :         }
      60             :       else
      61           0 :         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
      62             :         {
      63           0 :           num_m_args++;
      64           0 :           ip6_set = true;
      65             :         }
      66             :       else
      67           0 :         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
      68             :         {
      69           0 :           num_m_args++;
      70           0 :           ip6_set = true;
      71             :         }
      72           0 :       else if (unformat (line_input, "%U", unformat_tunnel_mode, &mode))
      73             :         {
      74           0 :           num_m_args++;
      75             :         }
      76           0 :       else if (unformat (line_input, "outer-table-id %d", &table_id))
      77             :         ;
      78             :       else
      79           0 :         if (unformat
      80             :             (line_input, "flags %U", unformat_tunnel_encap_decap_flags,
      81             :              &flags))
      82             :         ;
      83             :       else
      84             :         {
      85             :           error =
      86           0 :             clib_error_return (0, "unknown input `%U'", format_unformat_error,
      87             :                                line_input);
      88           0 :           goto done;
      89             :         }
      90             :     }
      91             : 
      92           0 :   if (num_m_args < 2)
      93             :     {
      94           0 :       error = clib_error_return (0, "mandatory argument(s) missing");
      95           0 :       goto done;
      96             :     }
      97           0 :   if (ip4_set && ip6_set)
      98             :     {
      99             :       error =
     100           0 :         clib_error_return (0,
     101             :                            "source and destination must be of same address family");
     102           0 :       goto done;
     103             :     }
     104             : 
     105           0 :   fib_index = fib_table_find (fib_ip_proto (ip6_set), table_id);
     106             : 
     107           0 :   if (~0 == fib_index)
     108             :     {
     109           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
     110             :     }
     111             :   else
     112             :     {
     113           0 :       rv = ipip_add_tunnel (ip6_set ? IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4,
     114             :                             instance,
     115             :                             &src,
     116             :                             &dst,
     117             :                             fib_index,
     118             :                             flags, IP_DSCP_CS0, mode, &sw_if_index);
     119             :     }
     120             : 
     121           0 :   switch (rv)
     122             :     {
     123           0 :     case 0:
     124           0 :       vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name,
     125             :                        vnet_get_main (), sw_if_index);
     126           0 :       break;
     127           0 :     case VNET_API_ERROR_IF_ALREADY_EXISTS:
     128           0 :       error = clib_error_return (0, "IPIP tunnel already exists...");
     129           0 :       goto done;
     130           0 :     case VNET_API_ERROR_NO_SUCH_FIB:
     131             :       error =
     132           0 :         clib_error_return (0, "outer fib ID %d doesn't exist\n", fib_index);
     133           0 :       goto done;
     134           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
     135           0 :       error = clib_error_return (0, "IPIP tunnel doesn't exist");
     136           0 :       goto done;
     137           0 :     case VNET_API_ERROR_INSTANCE_IN_USE:
     138           0 :       error = clib_error_return (0, "Instance is in use");
     139           0 :       goto done;
     140           0 :     case VNET_API_ERROR_INVALID_DST_ADDRESS:
     141             :       error =
     142           0 :         clib_error_return (0,
     143             :                            "destination IP address when mode is multi-point");
     144           0 :       goto done;
     145           0 :     default:
     146             :       error =
     147           0 :         clib_error_return (0, "vnet_ipip_add_del_tunnel returned %d", rv);
     148           0 :       goto done;
     149             :     }
     150             : 
     151           0 : done:
     152           0 :   unformat_free (line_input);
     153             : 
     154           0 :   return error;
     155             : }
     156             : 
     157             : static clib_error_t *
     158           0 : delete_ipip_tunnel_command_fn (vlib_main_t * vm,
     159             :                                unformat_input_t * input,
     160             :                                vlib_cli_command_t * cmd)
     161             : {
     162           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     163             :   int rv;
     164           0 :   u32 num_m_args = 0;
     165           0 :   u32 sw_if_index = ~0;
     166           0 :   clib_error_t *error = NULL;
     167             : 
     168             :   /* Get a line of input. */
     169           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     170           0 :     return 0;
     171             : 
     172           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     173             :     {
     174           0 :       if (unformat (line_input, "sw_if_index %d", &sw_if_index))
     175           0 :         num_m_args++;
     176             :       else
     177             :         {
     178             :           error =
     179           0 :             clib_error_return (0, "unknown input `%U'", format_unformat_error,
     180             :                                line_input);
     181           0 :           goto done;
     182             :         }
     183             :     }
     184             : 
     185           0 :   if (num_m_args < 1)
     186             :     {
     187           0 :       error = clib_error_return (0, "mandatory argument(s) missing");
     188           0 :       goto done;
     189             :     }
     190             : 
     191           0 :   rv = ipip_del_tunnel (sw_if_index);
     192           0 :   printf ("RV %d\n", rv);
     193             : 
     194           0 : done:
     195           0 :   unformat_free (line_input);
     196             : 
     197           0 :   return error;
     198             : }
     199             : 
     200             : /* *INDENT-OFF* */
     201      285289 : VLIB_CLI_COMMAND(create_ipip_tunnel_command, static) = {
     202             :     .path = "create ipip tunnel",
     203             :     .short_help = "create ipip tunnel src <addr> dst <addr> [instance <n>] "
     204             :                   "[outer-table-id <ID>] [p2mp]",
     205             :     .function = create_ipip_tunnel_command_fn,
     206             : };
     207      285289 : VLIB_CLI_COMMAND(delete_ipip_tunnel_command, static) = {
     208             :     .path = "delete ipip tunnel",
     209             :     .short_help = "delete ipip tunnel sw_if_index <sw_if_index>",
     210             :     .function = delete_ipip_tunnel_command_fn,
     211             : };
     212             : /* *INDENT-ON* */
     213             : 
     214             : static u8 *
     215           0 : format_ipip_tunnel (u8 * s, va_list * args)
     216             : {
     217           0 :   ipip_tunnel_t *t = va_arg (*args, ipip_tunnel_t *);
     218             : 
     219           0 :   ip46_type_t type =
     220           0 :     (t->transport == IPIP_TRANSPORT_IP4) ? IP46_TYPE_IP4 : IP46_TYPE_IP6;
     221             :   u32 table_id;
     222             : 
     223           0 :   table_id = fib_table_get_table_id (t->fib_index,
     224           0 :                                      fib_proto_from_ip46 (type));
     225           0 :   switch (t->mode)
     226             :     {
     227           0 :     case IPIP_MODE_6RD:
     228           0 :       s = format (s, "[%d] 6rd src %U ip6-pfx %U/%d ",
     229             :                   t->dev_instance,
     230             :                   format_ip46_address, &t->tunnel_src, type,
     231             :                   format_ip6_address, &t->sixrd.ip6_prefix,
     232           0 :                   t->sixrd.ip6_prefix_len);
     233           0 :       break;
     234           0 :     case IPIP_MODE_P2P:
     235           0 :       s = format (s, "[%d] instance %d src %U dst %U ",
     236             :                   t->dev_instance, t->user_instance,
     237             :                   format_ip46_address, &t->tunnel_src, type,
     238             :                   format_ip46_address, &t->tunnel_dst, type);
     239           0 :       break;
     240           0 :     case IPIP_MODE_P2MP:
     241           0 :       s = format (s, "[%d] instance %d p2mp src %U ",
     242             :                   t->dev_instance, t->user_instance,
     243             :                   format_ip46_address, &t->tunnel_src, type);
     244           0 :       break;
     245             :     }
     246             : 
     247           0 :   s = format (s, "table-ID %d sw-if-idx %d flags [%U] dscp %U",
     248             :               table_id, t->sw_if_index,
     249           0 :               format_tunnel_encap_decap_flags, t->flags,
     250           0 :               format_ip_dscp, t->dscp);
     251             : 
     252           0 :   return s;
     253             : }
     254             : 
     255             : static clib_error_t *
     256           0 : show_ipip_tunnel_command_fn (vlib_main_t * vm,
     257             :                              unformat_input_t * input,
     258             :                              vlib_cli_command_t * cmd)
     259             : {
     260           0 :   ipip_main_t *gm = &ipip_main;
     261             :   ipip_tunnel_t *t;
     262           0 :   u32 ti = ~0;
     263             : 
     264           0 :   if (pool_elts (gm->tunnels) == 0)
     265           0 :     vlib_cli_output (vm, "No IPIP tunnels configured...");
     266             : 
     267           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     268             :     {
     269           0 :       if (unformat (input, "%d", &ti))
     270             :         ;
     271             :       else
     272           0 :         break;
     273             :     }
     274             : 
     275           0 :   if (ti == ~0)
     276             :     {
     277             :     /* *INDENT-OFF* */
     278           0 :     pool_foreach (t, gm->tunnels)
     279           0 :                   {vlib_cli_output(vm, "%U", format_ipip_tunnel, t); }
     280             :     /* *INDENT-ON* */
     281             :     }
     282             :   else
     283             :     {
     284           0 :       if (pool_is_free_index (gm->tunnels, ti))
     285           0 :         return clib_error_return (0, "unknown index:%d", ti);
     286           0 :       t = pool_elt_at_index (gm->tunnels, ti);
     287           0 :       if (t)
     288           0 :         vlib_cli_output (vm, "%U", format_ipip_tunnel, t);
     289             :     }
     290           0 :   return 0;
     291             : }
     292             : 
     293             : /* *INDENT-OFF* */
     294      285289 : VLIB_CLI_COMMAND(show_ipip_tunnel_command, static) = {
     295             :     .path = "show ipip tunnel",
     296             :     .function = show_ipip_tunnel_command_fn,
     297             : };
     298             : /* *INDENT-ON* */
     299             : 
     300             : static u8 *
     301          30 : format_ipip_tunnel_key (u8 * s, va_list * args)
     302             : {
     303          30 :   ipip_tunnel_key_t *t = va_arg (*args, ipip_tunnel_key_t *);
     304             : 
     305          30 :   s = format (s, "src:%U dst:%U fib:%d transport:%d mode:%d",
     306             :               format_ip46_address, &t->src, IP46_TYPE_ANY,
     307             :               format_ip46_address, &t->dst, IP46_TYPE_ANY,
     308          30 :               t->fib_index, t->transport, t->mode);
     309             : 
     310          30 :   return (s);
     311             : }
     312             : 
     313             : static clib_error_t *
     314           6 : ipip_tunnel_hash_show (vlib_main_t * vm,
     315             :                        unformat_input_t * input, vlib_cli_command_t * cmd)
     316             : {
     317           6 :   ipip_main_t *im = &ipip_main;
     318             :   ipip_tunnel_key_t *key;
     319             :   u32 index;
     320             : 
     321             :   /* *INDENT-OFF* */
     322         420 :   hash_foreach(key, index, im->tunnel_by_key,
     323             :   ({
     324             :       vlib_cli_output (vm, " %U -> %d", format_ipip_tunnel_key, key, index);
     325             :   }));
     326             :   /* *INDENT-ON* */
     327             : 
     328           6 :   return NULL;
     329             : }
     330             : 
     331             : /**
     332             :  * show IPSEC tunnel protection hash tables
     333             :  */
     334             : /* *INDENT-OFF* */
     335      285289 : VLIB_CLI_COMMAND (ipip_tunnel_hash_show_node, static) =
     336             : {
     337             :   .path = "show ipip tunnel-hash",
     338             :   .function = ipip_tunnel_hash_show,
     339             :   .short_help =  "show ipip tunnel-hash",
     340             : };
     341             : /* *INDENT-ON* */
     342             : 
     343             : static clib_error_t *
     344           0 : create_sixrd_tunnel_command_fn (vlib_main_t * vm,
     345             :                                 unformat_input_t * input,
     346             :                                 vlib_cli_command_t * cmd)
     347             : {
     348           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     349             :   ip4_address_t ip4_prefix;
     350             :   ip6_address_t ip6_prefix;
     351             :   ip4_address_t ip4_src;
     352           0 :   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, sixrd_tunnel_index;
     353           0 :   u32 num_m_args = 0;
     354             :   /* Optional arguments */
     355           0 :   u32 ip4_table_id = 0, ip4_fib_index;
     356           0 :   u32 ip6_table_id = 0, ip6_fib_index;
     357           0 :   clib_error_t *error = 0;
     358           0 :   bool security_check = false;
     359             :   int rv;
     360             : 
     361             :   /* Get a line of input. */
     362           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     363           0 :     return 0;
     364           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     365             :     {
     366           0 :       if (unformat (line_input, "security-check"))
     367           0 :         security_check = true;
     368           0 :       else if (unformat (line_input, "ip6-pfx %U/%d", unformat_ip6_address,
     369             :                          &ip6_prefix, &ip6_prefix_len))
     370           0 :         num_m_args++;
     371           0 :       else if (unformat (line_input, "ip4-pfx %U/%d", unformat_ip4_address,
     372             :                          &ip4_prefix, &ip4_prefix_len))
     373           0 :         num_m_args++;
     374             :       else
     375           0 :         if (unformat
     376             :             (line_input, "ip4-src %U", unformat_ip4_address, &ip4_src))
     377           0 :         num_m_args++;
     378           0 :       else if (unformat (line_input, "ip4-table-id %d", &ip4_table_id))
     379             :         ;
     380           0 :       else if (unformat (line_input, "ip6-table-id %d", &ip6_table_id))
     381             :         ;
     382             :       else
     383             :         {
     384             :           error =
     385           0 :             clib_error_return (0, "unknown input `%U'", format_unformat_error,
     386             :                                line_input);
     387           0 :           goto done;
     388             :         }
     389             :     }
     390             : 
     391           0 :   if (num_m_args < 3)
     392             :     {
     393           0 :       error = clib_error_return (0, "mandatory argument(s) missing");
     394           0 :       goto done;
     395             :     }
     396           0 :   ip4_fib_index = fib_table_find (FIB_PROTOCOL_IP4, ip4_table_id);
     397           0 :   ip6_fib_index = fib_table_find (FIB_PROTOCOL_IP6, ip6_table_id);
     398             : 
     399           0 :   if (~0 == ip4_fib_index)
     400             :     {
     401           0 :       error = clib_error_return (0, "No such IP4 table %d", ip4_table_id);
     402           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
     403             :     }
     404           0 :   else if (~0 == ip6_fib_index)
     405             :     {
     406           0 :       error = clib_error_return (0, "No such IP6 table %d", ip6_table_id);
     407           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
     408             :     }
     409             :   else
     410             :     {
     411           0 :       rv = sixrd_add_tunnel (&ip6_prefix, ip6_prefix_len, &ip4_prefix,
     412             :                              ip4_prefix_len, &ip4_src, security_check,
     413             :                              ip4_fib_index, ip6_fib_index,
     414             :                              &sixrd_tunnel_index);
     415             : 
     416           0 :       if (rv)
     417           0 :         error = clib_error_return (0, "adding tunnel failed %d", rv);
     418             :     }
     419             : 
     420           0 : done:
     421           0 :   unformat_free (line_input);
     422             : 
     423           0 :   return error;
     424             : }
     425             : 
     426             : static clib_error_t *
     427           0 : delete_sixrd_tunnel_command_fn (vlib_main_t * vm,
     428             :                                 unformat_input_t * input,
     429             :                                 vlib_cli_command_t * cmd)
     430             : {
     431           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     432           0 :   u32 num_m_args = 0;
     433             :   /* Optional arguments */
     434           0 :   clib_error_t *error = 0;
     435           0 :   u32 sw_if_index = ~0;
     436             : 
     437             :   /* Get a line of input. */
     438           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     439           0 :     return 0;
     440           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     441             :     {
     442           0 :       if (unformat (line_input, "sw_if_index %d", &sw_if_index))
     443           0 :         num_m_args++;
     444             :       else
     445             :         {
     446             :           error =
     447           0 :             clib_error_return (0, "unknown input `%U'", format_unformat_error,
     448             :                                line_input);
     449           0 :           goto done;
     450             :         }
     451             :     }
     452             : 
     453           0 :   if (num_m_args < 1)
     454             :     {
     455           0 :       error = clib_error_return (0, "mandatory argument(s) missing");
     456           0 :       goto done;
     457             :     }
     458           0 :   int rv = sixrd_del_tunnel (sw_if_index);
     459           0 :   printf ("RV %d\n", rv);
     460             : 
     461           0 : done:
     462           0 :   unformat_free (line_input);
     463             : 
     464           0 :   return error;
     465             : }
     466             : 
     467             : /* *INDENT-OFF* */
     468      285289 : VLIB_CLI_COMMAND(create_sixrd_tunnel_command, static) = {
     469             :     .path = "create 6rd tunnel",
     470             :     .short_help = "create 6rd tunnel ip6-pfx <ip6-pfx> ip4-pfx <ip4-pfx> "
     471             :                   "ip4-src <ip4-addr> ip4-table-id <ID> ip6-table-id <ID> "
     472             :                   "[security-check]",
     473             :     .function = create_sixrd_tunnel_command_fn,
     474             : };
     475      285289 : VLIB_CLI_COMMAND(delete_sixrd_tunnel_command, static) = {
     476             :     .path = "delete 6rd tunnel",
     477             :     .short_help = "delete 6rd tunnel sw_if_index <sw_if_index>",
     478             :     .function = delete_sixrd_tunnel_command_fn,
     479             : };
     480             : /* *INDENT-ON* */
     481             : 
     482             : /*
     483             :  * fd.io coding-style-patch-verification: ON
     484             :  *
     485             :  * Local Variables:
     486             :  * eval: (c-set-style "gnu")
     487             :  * End:
     488             :  */

Generated by: LCOV version 1.14