LCOV - code coverage report
Current view: top level - vnet/ip - ip_test.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 769 0.0 %
Date: 2023-07-05 22:20:52 Functions: 0 73 0.0 %

          Line data    Source code
       1             : /*
       2             :  *------------------------------------------------------------------
       3             :  * Copyright (c) 2021 Cisco and/or its affiliates.
       4             :  * Licensed under the Apache License, Version 2.0 (the "License");
       5             :  * you may not use this file except in compliance with the License.
       6             :  * You may obtain a copy of the License at:
       7             :  *
       8             :  *     http://www.apache.org/licenses/LICENSE-2.0
       9             :  *
      10             :  * Unless required by applicable law or agreed to in writing, software
      11             :  * distributed under the License is distributed on an "AS IS" BASIS,
      12             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13             :  * See the License for the specific language governing permissions and
      14             :  * limitations under the License.
      15             :  *------------------------------------------------------------------
      16             :  */
      17             : 
      18             : #include <vat/vat.h>
      19             : #include <vlibapi/api.h>
      20             : #include <vlibmemory/api.h>
      21             : #include <vppinfra/error.h>
      22             : #include <vpp/api/types.h>
      23             : #include <vnet/mpls/packet.h>
      24             : #include <vnet/ip/ip_types_api.h>
      25             : 
      26             : #define __plugin_msg_base ip_test_main.msg_id_base
      27             : #include <vlibapi/vat_helper_macros.h>
      28             : 
      29             : /* Declare message IDs */
      30             : #include <vnet/format_fns.h>
      31             : #include <vnet/ip/ip.api_enum.h>
      32             : #include <vnet/ip/ip.api_types.h>
      33             : #include <vlibmemory/vlib.api_types.h>
      34             : 
      35             : #define vl_endianfun /* define message structures */
      36             : #include <vnet/ip/ip.api.h>
      37             : #undef vl_endianfun
      38             : 
      39             : #define vl_calcsizefun
      40             : #include <vnet/ip/ip.api.h>
      41             : #undef vl_calcsizefun
      42             : 
      43             : typedef struct
      44             : {
      45             :   /* API message ID base */
      46             :   u16 msg_id_base;
      47             :   vat_main_t *vat_main;
      48             : } ip_test_main_t;
      49             : 
      50             : static ip_test_main_t ip_test_main;
      51             : 
      52             : static int
      53           0 : api_ip_route_add_del_v2 (vat_main_t *vam)
      54             : {
      55           0 :   return -1;
      56             : }
      57             : 
      58             : static void
      59           0 : set_ip4_address (vl_api_address_t *a, u32 v)
      60             : {
      61           0 :   if (a->af == ADDRESS_IP4)
      62             :     {
      63           0 :       ip4_address_t *i = (ip4_address_t *) &a->un.ip4;
      64           0 :       i->as_u32 = v;
      65             :     }
      66           0 : }
      67             : 
      68             : static void
      69           0 : increment_v4_address (vl_api_ip4_address_t *i)
      70             : {
      71           0 :   ip4_address_t *a = (ip4_address_t *) i;
      72             :   u32 v;
      73             : 
      74           0 :   v = ntohl (a->as_u32) + 1;
      75           0 :   a->as_u32 = ntohl (v);
      76           0 : }
      77             : 
      78             : static void
      79           0 : increment_v6_address (vl_api_ip6_address_t *i)
      80             : {
      81           0 :   ip6_address_t *a = (ip6_address_t *) i;
      82             :   u64 v0, v1;
      83             : 
      84           0 :   v0 = clib_net_to_host_u64 (a->as_u64[0]);
      85           0 :   v1 = clib_net_to_host_u64 (a->as_u64[1]);
      86             : 
      87           0 :   v1 += 1;
      88           0 :   if (v1 == 0)
      89           0 :     v0 += 1;
      90           0 :   a->as_u64[0] = clib_net_to_host_u64 (v0);
      91           0 :   a->as_u64[1] = clib_net_to_host_u64 (v1);
      92           0 : }
      93             : 
      94             : static void
      95           0 : increment_address (vl_api_address_t *a)
      96             : {
      97           0 :   if (a->af == ADDRESS_IP4)
      98           0 :     increment_v4_address (&a->un.ip4);
      99           0 :   else if (a->af == ADDRESS_IP6)
     100           0 :     increment_v6_address (&a->un.ip6);
     101           0 : }
     102             : 
     103             : static uword
     104           0 : unformat_fib_path (unformat_input_t *input, va_list *args)
     105             : {
     106           0 :   vat_main_t *vam = va_arg (*args, vat_main_t *);
     107           0 :   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
     108             :   u32 weight, preference;
     109             :   mpls_label_t out_label;
     110             : 
     111           0 :   clib_memset (path, 0, sizeof (*path));
     112           0 :   path->weight = 1;
     113           0 :   path->sw_if_index = ~0;
     114           0 :   path->rpf_id = ~0;
     115           0 :   path->n_labels = 0;
     116             : 
     117           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     118             :     {
     119           0 :       if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
     120             :                     &path->nh.address.ip4, api_unformat_sw_if_index, vam,
     121             :                     &path->sw_if_index))
     122             :         {
     123           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP4;
     124             :         }
     125           0 :       else if (unformat (input, "%U %U", unformat_vl_api_ip6_address,
     126             :                          &path->nh.address.ip6, api_unformat_sw_if_index, vam,
     127             :                          &path->sw_if_index))
     128             :         {
     129           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP6;
     130             :         }
     131           0 :       else if (unformat (input, "weight %u", &weight))
     132             :         {
     133           0 :           path->weight = weight;
     134             :         }
     135           0 :       else if (unformat (input, "preference %u", &preference))
     136             :         {
     137           0 :           path->preference = preference;
     138             :         }
     139           0 :       else if (unformat (input, "%U next-hop-table %d",
     140             :                          unformat_vl_api_ip4_address, &path->nh.address.ip4,
     141             :                          &path->table_id))
     142             :         {
     143           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP4;
     144             :         }
     145           0 :       else if (unformat (input, "%U next-hop-table %d",
     146             :                          unformat_vl_api_ip6_address, &path->nh.address.ip6,
     147             :                          &path->table_id))
     148             :         {
     149           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP6;
     150             :         }
     151           0 :       else if (unformat (input, "%U", unformat_vl_api_ip4_address,
     152             :                          &path->nh.address.ip4))
     153             :         {
     154             :           /*
     155             :            * the recursive next-hops are by default in the default table
     156             :            */
     157           0 :           path->table_id = 0;
     158           0 :           path->sw_if_index = ~0;
     159           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP4;
     160             :         }
     161           0 :       else if (unformat (input, "%U", unformat_vl_api_ip6_address,
     162             :                          &path->nh.address.ip6))
     163             :         {
     164             :           /*
     165             :            * the recursive next-hops are by default in the default table
     166             :            */
     167           0 :           path->table_id = 0;
     168           0 :           path->sw_if_index = ~0;
     169           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP6;
     170             :         }
     171           0 :       else if (unformat (input, "resolve-via-host"))
     172             :         {
     173           0 :           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
     174             :         }
     175           0 :       else if (unformat (input, "resolve-via-attached"))
     176             :         {
     177           0 :           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
     178             :         }
     179           0 :       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
     180             :         {
     181           0 :           path->type = FIB_API_PATH_TYPE_LOCAL;
     182           0 :           path->sw_if_index = ~0;
     183           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP4;
     184             :         }
     185           0 :       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
     186             :         {
     187           0 :           path->type = FIB_API_PATH_TYPE_LOCAL;
     188           0 :           path->sw_if_index = ~0;
     189           0 :           path->proto = FIB_API_PATH_NH_PROTO_IP6;
     190             :         }
     191           0 :       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
     192             :         ;
     193           0 :       else if (unformat (input, "via-label %d", &path->nh.via_label))
     194             :         {
     195           0 :           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
     196           0 :           path->sw_if_index = ~0;
     197             :         }
     198           0 :       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
     199             :         {
     200           0 :           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
     201           0 :           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
     202             :         }
     203           0 :       else if (unformat (input, "local"))
     204             :         {
     205           0 :           path->type = FIB_API_PATH_TYPE_LOCAL;
     206             :         }
     207           0 :       else if (unformat (input, "out-labels"))
     208             :         {
     209           0 :           while (unformat (input, "%d", &out_label))
     210             :             {
     211           0 :               path->label_stack[path->n_labels].label = out_label;
     212           0 :               path->label_stack[path->n_labels].is_uniform = 0;
     213           0 :               path->label_stack[path->n_labels].ttl = 64;
     214           0 :               path->n_labels++;
     215             :             }
     216             :         }
     217           0 :       else if (unformat (input, "via"))
     218             :         {
     219             :           /* new path, back up and return */
     220           0 :           unformat_put_input (input);
     221           0 :           unformat_put_input (input);
     222           0 :           unformat_put_input (input);
     223           0 :           unformat_put_input (input);
     224           0 :           break;
     225             :         }
     226             :       else
     227             :         {
     228           0 :           return (0);
     229             :         }
     230             :     }
     231             : 
     232           0 :   path->proto = ntohl (path->proto);
     233           0 :   path->type = ntohl (path->type);
     234           0 :   path->flags = ntohl (path->flags);
     235           0 :   path->table_id = ntohl (path->table_id);
     236           0 :   path->sw_if_index = ntohl (path->sw_if_index);
     237             : 
     238           0 :   return (1);
     239             : }
     240             : 
     241             : static int
     242           0 : api_ip_route_add_del (vat_main_t *vam)
     243             : {
     244           0 :   unformat_input_t *i = vam->input;
     245             :   vl_api_ip_route_add_del_t *mp;
     246           0 :   u32 vrf_id = 0;
     247           0 :   u8 is_add = 1;
     248           0 :   u8 is_multipath = 0;
     249           0 :   u8 prefix_set = 0;
     250           0 :   u8 path_count = 0;
     251           0 :   vl_api_prefix_t pfx = {};
     252             :   vl_api_fib_path_t paths[8];
     253           0 :   int count = 1;
     254             :   int j;
     255           0 :   f64 before = 0;
     256           0 :   u32 random_add_del = 0;
     257           0 :   u32 *random_vector = 0;
     258           0 :   u32 random_seed = 0xdeaddabe;
     259             : 
     260             :   /* Parse args required to build the message */
     261           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     262             :     {
     263           0 :       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
     264           0 :         prefix_set = 1;
     265           0 :       else if (unformat (i, "del"))
     266           0 :         is_add = 0;
     267           0 :       else if (unformat (i, "add"))
     268           0 :         is_add = 1;
     269           0 :       else if (unformat (i, "vrf %d", &vrf_id))
     270             :         ;
     271           0 :       else if (unformat (i, "count %d", &count))
     272             :         ;
     273           0 :       else if (unformat (i, "random"))
     274           0 :         random_add_del = 1;
     275           0 :       else if (unformat (i, "multipath"))
     276           0 :         is_multipath = 1;
     277           0 :       else if (unformat (i, "seed %d", &random_seed))
     278             :         ;
     279           0 :       else if (unformat (i, "via %U", unformat_fib_path, vam,
     280           0 :                          &paths[path_count]))
     281             :         {
     282           0 :           path_count++;
     283           0 :           if (8 == path_count)
     284             :             {
     285           0 :               errmsg ("max 8 paths");
     286           0 :               return -99;
     287             :             }
     288             :         }
     289             :       else
     290             :         {
     291           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
     292           0 :           return -99;
     293             :         }
     294             :     }
     295             : 
     296           0 :   if (!path_count)
     297             :     {
     298           0 :       errmsg ("specify a path; via ...");
     299           0 :       return -99;
     300             :     }
     301           0 :   if (prefix_set == 0)
     302             :     {
     303           0 :       errmsg ("missing prefix");
     304           0 :       return -99;
     305             :     }
     306             : 
     307             :   /* Generate a pile of unique, random routes */
     308           0 :   if (random_add_del)
     309             :     {
     310           0 :       ip4_address_t *i = (ip4_address_t *) &paths[0].nh.address.ip4;
     311             :       u32 this_random_address;
     312             :       uword *random_hash;
     313             : 
     314           0 :       random_hash = hash_create (count, sizeof (uword));
     315             : 
     316           0 :       hash_set (random_hash, i->as_u32, 1);
     317           0 :       for (j = 0; j <= count; j++)
     318             :         {
     319             :           do
     320             :             {
     321           0 :               this_random_address = random_u32 (&random_seed);
     322           0 :               this_random_address = clib_host_to_net_u32 (this_random_address);
     323             :             }
     324           0 :           while (hash_get (random_hash, this_random_address));
     325           0 :           vec_add1 (random_vector, this_random_address);
     326           0 :           hash_set (random_hash, this_random_address, 1);
     327             :         }
     328           0 :       hash_free (random_hash);
     329           0 :       set_ip4_address (&pfx.address, random_vector[0]);
     330             :     }
     331             : 
     332           0 :   if (count > 1)
     333             :     {
     334             :       /* Turn on async mode */
     335           0 :       vam->async_mode = 1;
     336           0 :       vam->async_errors = 0;
     337           0 :       before = vat_time_now (vam);
     338             :     }
     339             : 
     340           0 :   for (j = 0; j < count; j++)
     341             :     {
     342             :       /* Construct the API message */
     343           0 :       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
     344             : 
     345           0 :       mp->is_add = is_add;
     346           0 :       mp->is_multipath = is_multipath;
     347             : 
     348           0 :       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
     349           0 :       mp->route.table_id = ntohl (vrf_id);
     350           0 :       mp->route.n_paths = path_count;
     351             : 
     352           0 :       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
     353             : 
     354           0 :       if (random_add_del)
     355           0 :         set_ip4_address (&pfx.address, random_vector[j + 1]);
     356             :       else
     357           0 :         increment_address (&pfx.address);
     358             :       /* send it... */
     359           0 :       S (mp);
     360             :       /* If we receive SIGTERM, stop now... */
     361           0 :       if (vam->do_exit)
     362           0 :         break;
     363             :     }
     364             : 
     365             :   /* When testing multiple add/del ops, use a control-ping to sync */
     366           0 :   if (count > 1)
     367             :     {
     368             :       vl_api_control_ping_t *mp_ping;
     369             :       f64 after;
     370             :       f64 timeout;
     371             : 
     372             :       /* Shut off async mode */
     373           0 :       vam->async_mode = 0;
     374             : 
     375           0 :       PING (&ip_test_main, mp_ping);
     376           0 :       S (mp_ping);
     377             : 
     378           0 :       timeout = vat_time_now (vam) + 1.0;
     379           0 :       while (vat_time_now (vam) < timeout)
     380           0 :         if (vam->result_ready == 1)
     381           0 :           goto out;
     382           0 :       vam->retval = -99;
     383             : 
     384           0 :     out:
     385           0 :       if (vam->retval == -99)
     386           0 :         errmsg ("timeout");
     387             : 
     388           0 :       if (vam->async_errors > 0)
     389             :         {
     390           0 :           errmsg ("%d asynchronous errors", vam->async_errors);
     391           0 :           vam->retval = -98;
     392             :         }
     393           0 :       vam->async_errors = 0;
     394           0 :       after = vat_time_now (vam);
     395             : 
     396             :       /* slim chance, but we might have eaten SIGTERM on the first iteration */
     397           0 :       if (j > 0)
     398           0 :         count = j;
     399             : 
     400           0 :       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
     401           0 :              after - before, count / (after - before));
     402             :     }
     403             :   else
     404             :     {
     405             :       int ret;
     406             : 
     407             :       /* Wait for a reply... */
     408           0 :       W (ret);
     409           0 :       return ret;
     410             :     }
     411             : 
     412             :   /* Return the good/bad news */
     413           0 :   return (vam->retval);
     414             : }
     415             : 
     416             : static int
     417           0 : api_ip_table_add_del (vat_main_t *vam)
     418             : {
     419           0 :   unformat_input_t *i = vam->input;
     420             :   vl_api_ip_table_add_del_t *mp;
     421           0 :   u32 table_id = ~0;
     422           0 :   u8 is_ipv6 = 0;
     423           0 :   u8 is_add = 1;
     424           0 :   int ret = 0;
     425             : 
     426             :   /* Parse args required to build the message */
     427           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     428             :     {
     429           0 :       if (unformat (i, "ipv6"))
     430           0 :         is_ipv6 = 1;
     431           0 :       else if (unformat (i, "del"))
     432           0 :         is_add = 0;
     433           0 :       else if (unformat (i, "add"))
     434           0 :         is_add = 1;
     435           0 :       else if (unformat (i, "table %d", &table_id))
     436             :         ;
     437             :       else
     438             :         {
     439           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
     440           0 :           return -99;
     441             :         }
     442             :     }
     443             : 
     444           0 :   if (~0 == table_id)
     445             :     {
     446           0 :       errmsg ("missing table-ID");
     447           0 :       return -99;
     448             :     }
     449             : 
     450             :   /* Construct the API message */
     451           0 :   M (IP_TABLE_ADD_DEL, mp);
     452             : 
     453           0 :   mp->table.table_id = ntohl (table_id);
     454           0 :   mp->table.is_ip6 = is_ipv6;
     455           0 :   mp->is_add = is_add;
     456             : 
     457             :   /* send it... */
     458           0 :   S (mp);
     459             : 
     460             :   /* Wait for a reply... */
     461           0 :   W (ret);
     462             : 
     463           0 :   return ret;
     464             : }
     465             : 
     466             : static int
     467           0 : api_ip_table_replace_begin (vat_main_t *vam)
     468             : {
     469           0 :   unformat_input_t *i = vam->input;
     470             :   vl_api_ip_table_replace_begin_t *mp;
     471           0 :   u32 table_id = 0;
     472           0 :   u8 is_ipv6 = 0;
     473             : 
     474             :   int ret;
     475           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     476             :     {
     477           0 :       if (unformat (i, "table %d", &table_id))
     478             :         ;
     479           0 :       else if (unformat (i, "ipv6"))
     480           0 :         is_ipv6 = 1;
     481             :       else
     482             :         {
     483           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
     484           0 :           return -99;
     485             :         }
     486             :     }
     487             : 
     488           0 :   M (IP_TABLE_REPLACE_BEGIN, mp);
     489             : 
     490           0 :   mp->table.table_id = ntohl (table_id);
     491           0 :   mp->table.is_ip6 = is_ipv6;
     492             : 
     493           0 :   S (mp);
     494           0 :   W (ret);
     495           0 :   return ret;
     496             : }
     497             : 
     498             : static int
     499           0 : api_ip_table_flush (vat_main_t *vam)
     500             : {
     501           0 :   unformat_input_t *i = vam->input;
     502             :   vl_api_ip_table_flush_t *mp;
     503           0 :   u32 table_id = 0;
     504           0 :   u8 is_ipv6 = 0;
     505             : 
     506             :   int ret;
     507           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     508             :     {
     509           0 :       if (unformat (i, "table %d", &table_id))
     510             :         ;
     511           0 :       else if (unformat (i, "ipv6"))
     512           0 :         is_ipv6 = 1;
     513             :       else
     514             :         {
     515           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
     516           0 :           return -99;
     517             :         }
     518             :     }
     519             : 
     520           0 :   M (IP_TABLE_FLUSH, mp);
     521             : 
     522           0 :   mp->table.table_id = ntohl (table_id);
     523           0 :   mp->table.is_ip6 = is_ipv6;
     524             : 
     525           0 :   S (mp);
     526           0 :   W (ret);
     527           0 :   return ret;
     528             : }
     529             : 
     530             : static int
     531           0 : api_ip_table_allocate (vat_main_t *vam)
     532             : {
     533           0 :   return -1;
     534             : }
     535             : 
     536             : static void
     537           0 : vl_api_ip_table_allocate_reply_t_handler (vl_api_ip_table_allocate_reply_t *mp)
     538             : {
     539           0 : }
     540             : 
     541             : static void
     542           0 : vl_api_ip_route_add_del_v2_reply_t_handler (
     543             :   vl_api_ip_route_add_del_v2_reply_t *mp)
     544             : {
     545           0 : }
     546             : 
     547             : static void
     548           0 : vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t *mp)
     549             : {
     550           0 : }
     551             : 
     552             : static void
     553           0 : vl_api_ip_route_v2_details_t_handler (vl_api_ip_route_v2_details_t *mp)
     554             : {
     555           0 : }
     556             : 
     557             : static void
     558           0 : vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *mp)
     559             : {
     560           0 :   vat_main_t *vam = ip_test_main.vat_main;
     561           0 :   vam->result_ready = 1;
     562           0 : }
     563             : 
     564             : static void
     565           0 : vl_api_ip_route_lookup_reply_t_handler (vl_api_ip_route_lookup_reply_t *mp)
     566             : {
     567           0 : }
     568             : 
     569             : static void
     570           0 : vl_api_ip_route_lookup_v2_reply_t_handler (
     571             :   vl_api_ip_route_lookup_v2_reply_t *mp)
     572             : {
     573           0 : }
     574             : 
     575             : static int
     576           0 : api_set_ip_flow_hash_router_id (vat_main_t *vat)
     577             : {
     578           0 :   return -1;
     579             : }
     580             : 
     581             : static int
     582           0 : api_ip_route_lookup (vat_main_t *vat)
     583             : {
     584           0 :   return -1;
     585             : }
     586             : 
     587             : static int
     588           0 : api_ip_route_lookup_v2 (vat_main_t *vat)
     589             : {
     590           0 :   return -1;
     591             : }
     592             : 
     593             : static int
     594           0 : api_set_ip_flow_hash (vat_main_t *vam)
     595             : {
     596           0 :   unformat_input_t *i = vam->input;
     597             :   vl_api_set_ip_flow_hash_t *mp;
     598           0 :   u32 vrf_id = 0;
     599           0 :   u8 is_ipv6 = 0;
     600           0 :   u8 vrf_id_set = 0;
     601           0 :   u8 src = 0;
     602           0 :   u8 dst = 0;
     603           0 :   u8 sport = 0;
     604           0 :   u8 dport = 0;
     605           0 :   u8 proto = 0;
     606           0 :   u8 reverse = 0;
     607             :   int ret;
     608             : 
     609           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     610             :     {
     611           0 :       if (unformat (i, "vrf %d", &vrf_id))
     612           0 :         vrf_id_set = 1;
     613           0 :       else if (unformat (i, "ipv6"))
     614           0 :         is_ipv6 = 1;
     615           0 :       else if (unformat (i, "src"))
     616           0 :         src = 1;
     617           0 :       else if (unformat (i, "dst"))
     618           0 :         dst = 1;
     619           0 :       else if (unformat (i, "sport"))
     620           0 :         sport = 1;
     621           0 :       else if (unformat (i, "dport"))
     622           0 :         dport = 1;
     623           0 :       else if (unformat (i, "proto"))
     624           0 :         proto = 1;
     625           0 :       else if (unformat (i, "reverse"))
     626           0 :         reverse = 1;
     627             : 
     628             :       else
     629             :         {
     630           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
     631           0 :           return -99;
     632             :         }
     633             :     }
     634             : 
     635           0 :   if (vrf_id_set == 0)
     636             :     {
     637           0 :       errmsg ("missing vrf id");
     638           0 :       return -99;
     639             :     }
     640             : 
     641           0 :   M (SET_IP_FLOW_HASH, mp);
     642           0 :   mp->src = src;
     643           0 :   mp->dst = dst;
     644           0 :   mp->sport = sport;
     645           0 :   mp->dport = dport;
     646           0 :   mp->proto = proto;
     647           0 :   mp->reverse = reverse;
     648           0 :   mp->vrf_id = ntohl (vrf_id);
     649           0 :   mp->is_ipv6 = is_ipv6;
     650             : 
     651           0 :   S (mp);
     652           0 :   W (ret);
     653           0 :   return ret;
     654             : }
     655             : 
     656             : static int
     657           0 : api_mfib_signal_dump (vat_main_t *vat)
     658             : {
     659           0 :   return -1;
     660             : }
     661             : 
     662             : static int
     663           0 : api_ip_punt_police (vat_main_t *vat)
     664             : {
     665           0 :   return -1;
     666             : }
     667             : 
     668             : static int
     669           0 : api_ip_punt_redirect (vat_main_t *vat)
     670             : {
     671           0 :   return -1;
     672             : }
     673             : 
     674             : static int
     675           0 : api_add_del_ip_punt_redirect_v2 (vat_main_t *vat)
     676             : {
     677           0 :   return -1;
     678             : }
     679             : 
     680             : static int
     681           0 : api_ip_punt_redirect_dump (vat_main_t *vat)
     682             : {
     683           0 :   return -1;
     684             : }
     685             : 
     686             : static void
     687           0 : vl_api_ip_punt_redirect_details_t_handler (
     688             :   vl_api_ip_punt_redirect_details_t *mp)
     689             : {
     690             :   /**/
     691           0 : }
     692             : 
     693             : static int
     694           0 : api_ip_punt_redirect_v2_dump (vat_main_t *vat)
     695             : {
     696           0 :   return -1;
     697             : }
     698             : 
     699             : static void
     700           0 : vl_api_ip_punt_redirect_v2_details_t_handler (
     701             :   vl_api_ip_punt_redirect_v2_details_t *mp)
     702             : {
     703             :   /**/
     704           0 : }
     705             : 
     706             : static int
     707           0 : api_ip_address_dump (vat_main_t *vam)
     708             : {
     709           0 :   unformat_input_t *i = vam->input;
     710             :   vl_api_ip_address_dump_t *mp;
     711             :   vl_api_control_ping_t *mp_ping;
     712           0 :   u32 sw_if_index = ~0;
     713           0 :   u8 sw_if_index_set = 0;
     714           0 :   u8 ipv4_set = 0;
     715           0 :   u8 ipv6_set = 0;
     716             :   int ret;
     717             : 
     718           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     719             :     {
     720           0 :       if (unformat (i, "sw_if_index %d", &sw_if_index))
     721           0 :         sw_if_index_set = 1;
     722           0 :       else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
     723           0 :         sw_if_index_set = 1;
     724           0 :       else if (unformat (i, "ipv4"))
     725           0 :         ipv4_set = 1;
     726           0 :       else if (unformat (i, "ipv6"))
     727           0 :         ipv6_set = 1;
     728             :       else
     729           0 :         break;
     730             :     }
     731             : 
     732           0 :   if (ipv4_set && ipv6_set)
     733             :     {
     734           0 :       errmsg ("ipv4 and ipv6 flags cannot be both set");
     735           0 :       return -99;
     736             :     }
     737             : 
     738           0 :   if ((!ipv4_set) && (!ipv6_set))
     739             :     {
     740           0 :       errmsg ("no ipv4 nor ipv6 flag set");
     741           0 :       return -99;
     742             :     }
     743             : 
     744           0 :   if (sw_if_index_set == 0)
     745             :     {
     746           0 :       errmsg ("missing interface name or sw_if_index");
     747           0 :       return -99;
     748             :     }
     749             : 
     750           0 :   vam->current_sw_if_index = sw_if_index;
     751           0 :   vam->is_ipv6 = ipv6_set;
     752             : 
     753           0 :   M (IP_ADDRESS_DUMP, mp);
     754           0 :   mp->sw_if_index = ntohl (sw_if_index);
     755           0 :   mp->is_ipv6 = ipv6_set;
     756           0 :   S (mp);
     757             : 
     758             :   /* Use a control ping for synchronization */
     759           0 :   PING (&ip_test_main, mp_ping);
     760           0 :   S (mp_ping);
     761             : 
     762           0 :   W (ret);
     763           0 :   return ret;
     764             : }
     765             : 
     766             : static void
     767           0 : vl_api_sw_interface_ip6_get_link_local_address_reply_t_handler (
     768             :   vl_api_sw_interface_ip6_get_link_local_address_reply_t *mp)
     769             : {
     770           0 : }
     771             : 
     772             : static int
     773           0 : api_sw_interface_ip6_set_link_local_address (vat_main_t *vam)
     774             : {
     775           0 :   return -1;
     776             : }
     777             : 
     778             : static int
     779           0 : api_sw_interface_ip6_get_link_local_address (vat_main_t *vam)
     780             : {
     781           0 :   return -1;
     782             : }
     783             : 
     784             : static int
     785           0 : api_ip_path_mtu_replace_end (vat_main_t *vam)
     786             : {
     787           0 :   return -1;
     788             : }
     789             : 
     790             : static int
     791           0 : api_ioam_enable (vat_main_t *vam)
     792             : {
     793           0 :   unformat_input_t *input = vam->input;
     794             :   vl_api_ioam_enable_t *mp;
     795           0 :   u32 id = 0;
     796           0 :   int has_trace_option = 0;
     797           0 :   int has_pot_option = 0;
     798           0 :   int has_seqno_option = 0;
     799           0 :   int has_analyse_option = 0;
     800             :   int ret;
     801             : 
     802           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     803             :     {
     804           0 :       if (unformat (input, "trace"))
     805           0 :         has_trace_option = 1;
     806           0 :       else if (unformat (input, "pot"))
     807           0 :         has_pot_option = 1;
     808           0 :       else if (unformat (input, "seqno"))
     809           0 :         has_seqno_option = 1;
     810           0 :       else if (unformat (input, "analyse"))
     811           0 :         has_analyse_option = 1;
     812             :       else
     813           0 :         break;
     814             :     }
     815           0 :   M (IOAM_ENABLE, mp);
     816           0 :   mp->id = htons (id);
     817           0 :   mp->seqno = has_seqno_option;
     818           0 :   mp->analyse = has_analyse_option;
     819           0 :   mp->pot_enable = has_pot_option;
     820           0 :   mp->trace_enable = has_trace_option;
     821             : 
     822           0 :   S (mp);
     823           0 :   W (ret);
     824           0 :   return ret;
     825             : }
     826             : 
     827             : static int
     828           0 : api_ip_reassembly_get (vat_main_t *vam)
     829             : {
     830           0 :   return -1;
     831             : }
     832             : 
     833             : static int
     834           0 : api_ip_path_mtu_replace_begin (vat_main_t *vam)
     835             : {
     836           0 :   return -1;
     837             : }
     838             : 
     839             : static int
     840           0 : api_ip_path_mtu_update (vat_main_t *vam)
     841             : {
     842           0 :   return -1;
     843             : }
     844             : 
     845             : static int
     846           0 : api_ioam_disable (vat_main_t *vam)
     847             : {
     848             :   vl_api_ioam_disable_t *mp;
     849             :   int ret;
     850             : 
     851           0 :   M (IOAM_DISABLE, mp);
     852           0 :   S (mp);
     853           0 :   W (ret);
     854           0 :   return ret;
     855             : }
     856             : 
     857             : static int
     858           0 : api_ip_source_and_port_range_check_add_del (vat_main_t *vam)
     859             : {
     860           0 :   unformat_input_t *input = vam->input;
     861             :   vl_api_ip_source_and_port_range_check_add_del_t *mp;
     862             : 
     863           0 :   u16 *low_ports = 0;
     864           0 :   u16 *high_ports = 0;
     865             :   u16 this_low;
     866             :   u16 this_hi;
     867             :   vl_api_prefix_t prefix;
     868             :   u32 tmp, tmp2;
     869           0 :   u8 prefix_set = 0;
     870           0 :   u32 vrf_id = ~0;
     871           0 :   u8 is_add = 1;
     872             :   int ret;
     873             : 
     874           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     875             :     {
     876           0 :       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
     877           0 :         prefix_set = 1;
     878           0 :       else if (unformat (input, "vrf %d", &vrf_id))
     879             :         ;
     880           0 :       else if (unformat (input, "del"))
     881           0 :         is_add = 0;
     882           0 :       else if (unformat (input, "port %d", &tmp))
     883             :         {
     884           0 :           if (tmp == 0 || tmp > 65535)
     885             :             {
     886           0 :               errmsg ("port %d out of range", tmp);
     887           0 :               return -99;
     888             :             }
     889           0 :           this_low = tmp;
     890           0 :           this_hi = this_low + 1;
     891           0 :           vec_add1 (low_ports, this_low);
     892           0 :           vec_add1 (high_ports, this_hi);
     893             :         }
     894           0 :       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
     895             :         {
     896           0 :           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
     897             :             {
     898           0 :               errmsg ("incorrect range parameters");
     899           0 :               return -99;
     900             :             }
     901           0 :           this_low = tmp;
     902             :           /* Note: in debug CLI +1 is added to high before
     903             :              passing to real fn that does "the work"
     904             :              (ip_source_and_port_range_check_add_del).
     905             :              This fn is a wrapper around the binary API fn a
     906             :              control plane will call, which expects this increment
     907             :              to have occurred. Hence letting the binary API control
     908             :              plane fn do the increment for consistency between VAT
     909             :              and other control planes.
     910             :            */
     911           0 :           this_hi = tmp2;
     912           0 :           vec_add1 (low_ports, this_low);
     913           0 :           vec_add1 (high_ports, this_hi);
     914             :         }
     915             :       else
     916           0 :         break;
     917             :     }
     918             : 
     919           0 :   if (prefix_set == 0)
     920             :     {
     921           0 :       errmsg ("<address>/<mask> not specified");
     922           0 :       return -99;
     923             :     }
     924             : 
     925           0 :   if (vrf_id == ~0)
     926             :     {
     927           0 :       errmsg ("VRF ID required, not specified");
     928           0 :       return -99;
     929             :     }
     930             : 
     931           0 :   if (vrf_id == 0)
     932             :     {
     933           0 :       errmsg ("VRF ID should not be default. Should be distinct VRF for this "
     934             :               "purpose.");
     935           0 :       return -99;
     936             :     }
     937             : 
     938           0 :   if (vec_len (low_ports) == 0)
     939             :     {
     940           0 :       errmsg ("At least one port or port range required");
     941           0 :       return -99;
     942             :     }
     943             : 
     944           0 :   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
     945             : 
     946           0 :   mp->is_add = is_add;
     947             : 
     948           0 :   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
     949             : 
     950           0 :   mp->number_of_ranges = vec_len (low_ports);
     951             : 
     952           0 :   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
     953           0 :   vec_free (low_ports);
     954             : 
     955           0 :   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
     956           0 :   vec_free (high_ports);
     957             : 
     958           0 :   mp->vrf_id = ntohl (vrf_id);
     959             : 
     960           0 :   S (mp);
     961           0 :   W (ret);
     962           0 :   return ret;
     963             : }
     964             : 
     965             : static int
     966           0 : api_ip_reassembly_set (vat_main_t *vat)
     967             : {
     968           0 :   return -1;
     969             : }
     970             : 
     971             : static int
     972           0 : api_ip_container_proxy_add_del (vat_main_t *vam)
     973             : {
     974             :   vl_api_ip_container_proxy_add_del_t *mp;
     975           0 :   unformat_input_t *i = vam->input;
     976           0 :   u32 sw_if_index = ~0;
     977           0 :   vl_api_prefix_t pfx = {};
     978           0 :   u8 is_add = 1;
     979             :   int ret;
     980             : 
     981           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     982             :     {
     983           0 :       if (unformat (i, "del"))
     984           0 :         is_add = 0;
     985           0 :       else if (unformat (i, "add"))
     986             :         ;
     987           0 :       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
     988             :         ;
     989           0 :       else if (unformat (i, "sw_if_index %u", &sw_if_index))
     990             :         ;
     991             :       else
     992           0 :         break;
     993             :     }
     994           0 :   if (sw_if_index == ~0 || pfx.len == 0)
     995             :     {
     996           0 :       errmsg ("address and sw_if_index must be set");
     997           0 :       return -99;
     998             :     }
     999             : 
    1000           0 :   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
    1001             : 
    1002           0 :   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
    1003           0 :   mp->is_add = is_add;
    1004           0 :   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
    1005             : 
    1006           0 :   S (mp);
    1007           0 :   W (ret);
    1008           0 :   return ret;
    1009             : }
    1010             : 
    1011             : static int
    1012           0 : api_ip_reassembly_enable_disable (vat_main_t *vat)
    1013             : {
    1014           0 :   return -1;
    1015             : }
    1016             : 
    1017             : static int
    1018           0 : api_ip_local_reass_enable_disable (vat_main_t *vat)
    1019             : {
    1020           0 :   return -1;
    1021             : }
    1022             : 
    1023             : static int
    1024           0 : api_ip_local_reass_get (vat_main_t *vat)
    1025             : {
    1026           0 :   return -1;
    1027             : }
    1028             : 
    1029             : static void
    1030           0 : vl_api_ip_local_reass_get_reply_t_handler (
    1031             :   vl_api_ip_local_reass_get_reply_t *mp)
    1032             : {
    1033           0 : }
    1034             : 
    1035             : static void
    1036           0 : vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp)
    1037             : {
    1038           0 : }
    1039             : 
    1040             : int
    1041           0 : api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam)
    1042             : {
    1043           0 :   unformat_input_t *input = vam->input;
    1044             :   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
    1045           0 :   u32 sw_if_index = ~0;
    1046           0 :   int vrf_set = 0;
    1047           0 :   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
    1048           0 :   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
    1049           0 :   u8 is_add = 1;
    1050             :   int ret;
    1051             : 
    1052           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    1053             :     {
    1054           0 :       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
    1055             :         ;
    1056           0 :       else if (unformat (input, "sw_if_index %d", &sw_if_index))
    1057             :         ;
    1058           0 :       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
    1059           0 :         vrf_set = 1;
    1060           0 :       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
    1061           0 :         vrf_set = 1;
    1062           0 :       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
    1063           0 :         vrf_set = 1;
    1064           0 :       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
    1065           0 :         vrf_set = 1;
    1066           0 :       else if (unformat (input, "del"))
    1067           0 :         is_add = 0;
    1068             :       else
    1069           0 :         break;
    1070             :     }
    1071             : 
    1072           0 :   if (sw_if_index == ~0)
    1073             :     {
    1074           0 :       errmsg ("Interface required but not specified");
    1075           0 :       return -99;
    1076             :     }
    1077             : 
    1078           0 :   if (vrf_set == 0)
    1079             :     {
    1080           0 :       errmsg ("VRF ID required but not specified");
    1081           0 :       return -99;
    1082             :     }
    1083             : 
    1084           0 :   if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
    1085           0 :       udp_in_vrf_id == 0)
    1086             :     {
    1087           0 :       errmsg ("VRF ID should not be default. Should be distinct VRF for this "
    1088             :               "purpose.");
    1089           0 :       return -99;
    1090             :     }
    1091             : 
    1092             :   /* Construct the API message */
    1093           0 :   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
    1094             : 
    1095           0 :   mp->sw_if_index = ntohl (sw_if_index);
    1096           0 :   mp->is_add = is_add;
    1097           0 :   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
    1098           0 :   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
    1099           0 :   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
    1100           0 :   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
    1101             : 
    1102             :   /* send it... */
    1103           0 :   S (mp);
    1104             : 
    1105             :   /* Wait for a reply... */
    1106           0 :   W (ret);
    1107           0 :   return ret;
    1108             : }
    1109             : 
    1110             : static void
    1111           0 : vl_api_ip_container_proxy_details_t_handler (
    1112             :   vl_api_ip_container_proxy_details_t *mp)
    1113             : {
    1114           0 : }
    1115             : 
    1116             : static int
    1117           0 : api_ip_container_proxy_dump (vat_main_t *vam)
    1118             : {
    1119           0 :   return -1;
    1120             : }
    1121             : 
    1122             : static int
    1123           0 : api_ip_dump (vat_main_t *vam)
    1124             : {
    1125             :   vl_api_ip_dump_t *mp;
    1126             :   vl_api_control_ping_t *mp_ping;
    1127           0 :   unformat_input_t *in = vam->input;
    1128           0 :   int ipv4_set = 0;
    1129           0 :   int ipv6_set = 0;
    1130             :   int is_ipv6;
    1131             :   int i;
    1132             :   int ret;
    1133             : 
    1134           0 :   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
    1135             :     {
    1136           0 :       if (unformat (in, "ipv4"))
    1137           0 :         ipv4_set = 1;
    1138           0 :       else if (unformat (in, "ipv6"))
    1139           0 :         ipv6_set = 1;
    1140             :       else
    1141           0 :         break;
    1142             :     }
    1143             : 
    1144           0 :   if (ipv4_set && ipv6_set)
    1145             :     {
    1146           0 :       errmsg ("ipv4 and ipv6 flags cannot be both set");
    1147           0 :       return -99;
    1148             :     }
    1149             : 
    1150           0 :   if ((!ipv4_set) && (!ipv6_set))
    1151             :     {
    1152           0 :       errmsg ("no ipv4 nor ipv6 flag set");
    1153           0 :       return -99;
    1154             :     }
    1155             : 
    1156           0 :   is_ipv6 = ipv6_set;
    1157           0 :   vam->is_ipv6 = is_ipv6;
    1158             : 
    1159             :   /* free old data */
    1160           0 :   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
    1161             :     {
    1162           0 :       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
    1163             :     }
    1164           0 :   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
    1165             : 
    1166           0 :   M (IP_DUMP, mp);
    1167           0 :   mp->is_ipv6 = ipv6_set;
    1168           0 :   S (mp);
    1169             : 
    1170             :   /* Use a control ping for synchronization */
    1171           0 :   PING (&ip_test_main, mp_ping);
    1172           0 :   S (mp_ping);
    1173             : 
    1174           0 :   W (ret);
    1175           0 :   return ret;
    1176             : }
    1177             : 
    1178             : static void
    1179           0 : vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
    1180             : {
    1181           0 : }
    1182             : 
    1183             : static void
    1184           0 : vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
    1185             : {
    1186           0 :   vat_main_t *vam = ip_test_main.vat_main;
    1187           0 :   vam->result_ready = 1;
    1188           0 : }
    1189             : 
    1190             : static int
    1191           0 : api_ip_mroute_dump (vat_main_t *vam)
    1192             : {
    1193           0 :   unformat_input_t *input = vam->input;
    1194             :   vl_api_control_ping_t *mp_ping;
    1195             :   vl_api_ip_mroute_dump_t *mp;
    1196             :   int ret, is_ip6;
    1197             :   u32 table_id;
    1198             : 
    1199           0 :   is_ip6 = 0;
    1200           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    1201             :     {
    1202           0 :       if (unformat (input, "table_id %d", &table_id))
    1203             :         ;
    1204           0 :       else if (unformat (input, "ip6"))
    1205           0 :         is_ip6 = 1;
    1206           0 :       else if (unformat (input, "ip4"))
    1207           0 :         is_ip6 = 0;
    1208             :       else
    1209           0 :         break;
    1210             :     }
    1211           0 :   if (table_id == ~0)
    1212             :     {
    1213           0 :       errmsg ("missing table id");
    1214           0 :       return -99;
    1215             :     }
    1216             : 
    1217           0 :   M (IP_MROUTE_DUMP, mp);
    1218           0 :   mp->table.table_id = table_id;
    1219           0 :   mp->table.is_ip6 = is_ip6;
    1220           0 :   S (mp);
    1221             : 
    1222             :   /* Use a control ping for synchronization */
    1223           0 :   PING (&ip_test_main, mp_ping);
    1224           0 :   S (mp_ping);
    1225             : 
    1226           0 :   W (ret);
    1227           0 :   return ret;
    1228             : }
    1229             : 
    1230             : static int
    1231           0 : api_sw_interface_ip6_enable_disable (vat_main_t *vam)
    1232             : {
    1233           0 :   unformat_input_t *i = vam->input;
    1234             :   vl_api_sw_interface_ip6_enable_disable_t *mp;
    1235             :   u32 sw_if_index;
    1236           0 :   u8 sw_if_index_set = 0;
    1237           0 :   u8 enable = 0;
    1238             :   int ret;
    1239             : 
    1240           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    1241             :     {
    1242           0 :       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
    1243           0 :         sw_if_index_set = 1;
    1244           0 :       else if (unformat (i, "sw_if_index %d", &sw_if_index))
    1245           0 :         sw_if_index_set = 1;
    1246           0 :       else if (unformat (i, "enable"))
    1247           0 :         enable = 1;
    1248           0 :       else if (unformat (i, "disable"))
    1249           0 :         enable = 0;
    1250             :       else
    1251             :         {
    1252           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
    1253           0 :           return -99;
    1254             :         }
    1255             :     }
    1256             : 
    1257           0 :   if (sw_if_index_set == 0)
    1258             :     {
    1259           0 :       errmsg ("missing interface name or sw_if_index");
    1260           0 :       return -99;
    1261             :     }
    1262             : 
    1263           0 :   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
    1264             : 
    1265           0 :   mp->sw_if_index = ntohl (sw_if_index);
    1266           0 :   mp->enable = enable;
    1267             : 
    1268           0 :   S (mp);
    1269           0 :   W (ret);
    1270           0 :   return ret;
    1271             : }
    1272             : 
    1273             : static int
    1274           0 : api_set_ip_flow_hash_v2 (vat_main_t *vat)
    1275             : {
    1276           0 :   return -1;
    1277             : }
    1278             : 
    1279             : static int
    1280           0 : api_set_ip_flow_hash_v3 (vat_main_t *vat)
    1281             : {
    1282           0 :   return -1;
    1283             : }
    1284             : 
    1285             : static int
    1286           0 : api_ip_mroute_add_del (vat_main_t *vam)
    1287             : {
    1288           0 :   unformat_input_t *i = vam->input;
    1289           0 :   u8 path_set = 0, prefix_set = 0, is_add = 1;
    1290             :   vl_api_ip_mroute_add_del_t *mp;
    1291           0 :   mfib_entry_flags_t eflags = 0;
    1292             :   vl_api_mfib_path_t path;
    1293           0 :   vl_api_mprefix_t pfx = {};
    1294           0 :   u32 vrf_id = 0;
    1295             :   int ret;
    1296             : 
    1297             :   /* Parse args required to build the message */
    1298           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    1299             :     {
    1300           0 :       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
    1301             :         {
    1302           0 :           prefix_set = 1;
    1303           0 :           pfx.grp_address_length = htons (pfx.grp_address_length);
    1304             :         }
    1305           0 :       else if (unformat (i, "del"))
    1306           0 :         is_add = 0;
    1307           0 :       else if (unformat (i, "add"))
    1308           0 :         is_add = 1;
    1309           0 :       else if (unformat (i, "vrf %d", &vrf_id))
    1310             :         ;
    1311           0 :       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
    1312           0 :         path.itf_flags = htonl (path.itf_flags);
    1313           0 :       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
    1314             :         ;
    1315           0 :       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
    1316           0 :         path_set = 1;
    1317             :       else
    1318             :         {
    1319           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
    1320           0 :           return -99;
    1321             :         }
    1322             :     }
    1323             : 
    1324           0 :   if (prefix_set == 0)
    1325             :     {
    1326           0 :       errmsg ("missing addresses\n");
    1327           0 :       return -99;
    1328             :     }
    1329           0 :   if (path_set == 0)
    1330             :     {
    1331           0 :       errmsg ("missing path\n");
    1332           0 :       return -99;
    1333             :     }
    1334             : 
    1335             :   /* Construct the API message */
    1336           0 :   M (IP_MROUTE_ADD_DEL, mp);
    1337             : 
    1338           0 :   mp->is_add = is_add;
    1339           0 :   mp->is_multipath = 1;
    1340             : 
    1341           0 :   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
    1342           0 :   mp->route.table_id = htonl (vrf_id);
    1343           0 :   mp->route.n_paths = 1;
    1344           0 :   mp->route.entry_flags = htonl (eflags);
    1345             : 
    1346           0 :   clib_memcpy (&mp->route.paths, &path, sizeof (path));
    1347             : 
    1348             :   /* send it... */
    1349           0 :   S (mp);
    1350             :   /* Wait for a reply... */
    1351           0 :   W (ret);
    1352           0 :   return ret;
    1353             : }
    1354             : 
    1355             : static void
    1356           0 : vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
    1357             : {
    1358           0 :   vat_main_t *vam = ip_test_main.vat_main;
    1359           0 :   vam->result_ready = 1;
    1360           0 : }
    1361             : 
    1362             : static int
    1363           0 : api_ip_mtable_dump (vat_main_t *vam)
    1364             : {
    1365             :   vl_api_ip_mtable_dump_t *mp;
    1366             :   vl_api_control_ping_t *mp_ping;
    1367             :   int ret;
    1368             : 
    1369           0 :   M (IP_MTABLE_DUMP, mp);
    1370           0 :   S (mp);
    1371             : 
    1372             :   /* Use a control ping for synchronization */
    1373           0 :   PING (&ip_test_main, mp_ping);
    1374           0 :   S (mp_ping);
    1375             : 
    1376           0 :   W (ret);
    1377           0 :   return ret;
    1378             : }
    1379             : 
    1380             : static void
    1381           0 : vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
    1382             : {
    1383           0 :   vat_main_t *vam = ip_test_main.vat_main;
    1384           0 :   vam->result_ready = 1;
    1385           0 : }
    1386             : 
    1387             : static int
    1388           0 : api_ip_table_replace_end (vat_main_t *vam)
    1389             : {
    1390           0 :   unformat_input_t *i = vam->input;
    1391             :   vl_api_ip_table_replace_end_t *mp;
    1392           0 :   u32 table_id = 0;
    1393           0 :   u8 is_ipv6 = 0;
    1394             : 
    1395             :   int ret;
    1396           0 :   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    1397             :     {
    1398           0 :       if (unformat (i, "table %d", &table_id))
    1399             :         ;
    1400           0 :       else if (unformat (i, "ipv6"))
    1401           0 :         is_ipv6 = 1;
    1402             :       else
    1403             :         {
    1404           0 :           clib_warning ("parse error '%U'", format_unformat_error, i);
    1405           0 :           return -99;
    1406             :         }
    1407             :     }
    1408             : 
    1409           0 :   M (IP_TABLE_REPLACE_END, mp);
    1410             : 
    1411           0 :   mp->table.table_id = ntohl (table_id);
    1412           0 :   mp->table.is_ip6 = is_ipv6;
    1413             : 
    1414           0 :   S (mp);
    1415           0 :   W (ret);
    1416           0 :   return ret;
    1417             : }
    1418             : 
    1419             : static int
    1420           0 : api_ip_table_dump (vat_main_t *vam)
    1421             : {
    1422             :   vl_api_ip_table_dump_t *mp;
    1423             :   vl_api_control_ping_t *mp_ping;
    1424             :   int ret;
    1425             : 
    1426           0 :   M (IP_TABLE_DUMP, mp);
    1427           0 :   S (mp);
    1428             : 
    1429             :   /* Use a control ping for synchronization */
    1430           0 :   PING (&ip_test_main, mp_ping);
    1431           0 :   S (mp_ping);
    1432             : 
    1433           0 :   W (ret);
    1434           0 :   return ret;
    1435             : }
    1436             : 
    1437             : static void
    1438           0 : vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
    1439             : {
    1440           0 :   vat_main_t *vam = ip_test_main.vat_main;
    1441             : 
    1442           0 :   fformat (vam->ofp, "%s; table-id %d, prefix %U/%d", mp->table.name,
    1443             :            ntohl (mp->table.table_id));
    1444           0 :   vam->result_ready = 1;
    1445           0 : }
    1446             : 
    1447             : static int
    1448           0 : api_ip_path_mtu_get (vat_main_t *vat)
    1449             : {
    1450           0 :   return -1;
    1451             : }
    1452             : 
    1453             : static int
    1454           0 : api_ip_route_v2_dump (vat_main_t *vat)
    1455             : {
    1456           0 :   return -1;
    1457             : }
    1458             : 
    1459             : static void
    1460           0 : vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
    1461             : {
    1462           0 : }
    1463             : 
    1464             : static int
    1465           0 : api_ip_route_dump (vat_main_t *vam)
    1466             : {
    1467           0 :   unformat_input_t *input = vam->input;
    1468             :   vl_api_ip_route_dump_t *mp;
    1469             :   vl_api_control_ping_t *mp_ping;
    1470             :   u32 table_id;
    1471             :   u8 is_ip6;
    1472             :   int ret;
    1473             : 
    1474           0 :   is_ip6 = 0;
    1475           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    1476             :     {
    1477           0 :       if (unformat (input, "table_id %d", &table_id))
    1478             :         ;
    1479           0 :       else if (unformat (input, "ip6"))
    1480           0 :         is_ip6 = 1;
    1481           0 :       else if (unformat (input, "ip4"))
    1482           0 :         is_ip6 = 0;
    1483             :       else
    1484           0 :         break;
    1485             :     }
    1486           0 :   if (table_id == ~0)
    1487             :     {
    1488           0 :       errmsg ("missing table id");
    1489           0 :       return -99;
    1490             :     }
    1491             : 
    1492           0 :   M (IP_ROUTE_DUMP, mp);
    1493             : 
    1494           0 :   mp->table.table_id = table_id;
    1495           0 :   mp->table.is_ip6 = is_ip6;
    1496             : 
    1497           0 :   S (mp);
    1498             : 
    1499             :   /* Use a control ping for synchronization */
    1500           0 :   PING (&ip_test_main, mp_ping);
    1501           0 :   S (mp_ping);
    1502             : 
    1503           0 :   W (ret);
    1504           0 :   return ret;
    1505             : }
    1506             : 
    1507             : static void
    1508           0 : vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
    1509             : {
    1510           0 :   vat_main_t *vam = ip_test_main.vat_main;
    1511             :   static ip_address_details_t empty_ip_address_details = { { 0 } };
    1512           0 :   ip_address_details_t *address = NULL;
    1513           0 :   ip_details_t *current_ip_details = NULL;
    1514           0 :   ip_details_t *details = NULL;
    1515             : 
    1516           0 :   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
    1517             : 
    1518           0 :   if (!details || vam->current_sw_if_index >= vec_len (details) ||
    1519           0 :       !details[vam->current_sw_if_index].present)
    1520             :     {
    1521           0 :       errmsg ("ip address details arrived but not stored");
    1522           0 :       errmsg ("ip_dump should be called first");
    1523           0 :       return;
    1524             :     }
    1525             : 
    1526           0 :   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
    1527             : 
    1528             : #define addresses (current_ip_details->addr)
    1529             : 
    1530           0 :   vec_validate_init_empty (addresses, vec_len (addresses),
    1531             :                            empty_ip_address_details);
    1532             : 
    1533           0 :   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
    1534             : 
    1535           0 :   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
    1536           0 :   address->prefix_length = mp->prefix.len;
    1537             : #undef addresses
    1538             : }
    1539             : 
    1540             : static int
    1541           0 : api_ip_unnumbered_dump (vat_main_t *vam)
    1542             : {
    1543           0 :   return -1;
    1544             : }
    1545             : 
    1546             : static void
    1547           0 : vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
    1548             : {
    1549           0 : }
    1550             : 
    1551             : static void
    1552           0 : vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
    1553             : {
    1554           0 :   vat_main_t *vam = &vat_main;
    1555             :   static ip_details_t empty_ip_details = { 0 };
    1556           0 :   ip_details_t *ip = NULL;
    1557           0 :   u32 sw_if_index = ~0;
    1558             : 
    1559           0 :   sw_if_index = ntohl (mp->sw_if_index);
    1560             : 
    1561           0 :   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
    1562             :                            sw_if_index, empty_ip_details);
    1563             : 
    1564           0 :   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
    1565             :                          sw_if_index);
    1566             : 
    1567           0 :   ip->present = 1;
    1568           0 : }
    1569             : 
    1570             : #include <vnet/ip/ip.api_test.c>
    1571             : 
    1572             : /*
    1573             :  * fd.io coding-style-patch-verification: ON
    1574             :  *
    1575             :  * Local Variables:
    1576             :  * eval: (c-set-style "gnu")
    1577             :  * End:
    1578             :  */

Generated by: LCOV version 1.14