LCOV - code coverage report
Current view: top level - plugins/tracedump - tracedump.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 16 271 5.9 %
Date: 2023-10-26 01:39:38 Functions: 5 15 33.3 %

          Line data    Source code
       1             : /*
       2             :  * tracedump.c - skeleton vpp engine plug-in
       3             :  *
       4             :  * Copyright (c) <current-year> <your-organization>
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at:
       8             :  *
       9             :  *     http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : #include <vnet/vnet.h>
      19             : #include <vnet/plugin/plugin.h>
      20             : #include <tracedump/tracedump.h>
      21             : #include <vlib/trace.h>
      22             : 
      23             : #include <vlibapi/api.h>
      24             : #include <vlibmemory/api.h>
      25             : #include <vpp/app/version.h>
      26             : #include <stdbool.h>
      27             : 
      28             : #include <tracedump/tracedump.api_enum.h>
      29             : #include <tracedump/tracedump.api_types.h>
      30             : 
      31             : #define REPLY_MSG_ID_BASE tdmp->msg_id_base
      32             : #include <vlibapi/api_helper_macros.h>
      33             : 
      34             : tracedump_main_t tracedump_main;
      35             : 
      36             : 
      37             : static void
      38           0 : vl_api_trace_set_filters_t_handler (vl_api_trace_set_filters_t * mp)
      39             : {
      40           0 :   vlib_main_t *vm = vlib_get_main ();
      41           0 :   tracedump_main_t *tdmp = &tracedump_main;
      42           0 :   u32 node_index = clib_net_to_host_u32 (mp->node_index);
      43           0 :   u32 flag = clib_net_to_host_u32 (mp->flag);
      44           0 :   u32 count = clib_net_to_host_u32 (mp->count);
      45             :   vl_api_trace_set_filters_reply_t *rmp;
      46           0 :   int rv = 0;
      47             : 
      48           0 :   if (flag == TRACE_FF_NONE)
      49             :     {
      50           0 :       count = node_index = 0;
      51             :     }
      52           0 :   else if (flag != TRACE_FF_INCLUDE_NODE && flag != TRACE_FF_EXCLUDE_NODE)
      53             :     {
      54           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
      55           0 :       goto done;
      56             :     }
      57             : 
      58             :   vlib_node_t *node;
      59           0 :   node = vlib_get_node (vm, node_index);
      60           0 :   if (!node)
      61             :     {
      62           0 :       rv = VNET_API_ERROR_NO_SUCH_NODE;
      63           0 :       goto done;
      64             :     }
      65             : 
      66           0 :   trace_filter_set (node_index, flag, count);
      67             : 
      68           0 : done:
      69           0 :   REPLY_MACRO (VL_API_TRACE_SET_FILTERS_REPLY);
      70             : }
      71             : 
      72             : 
      73             : static void
      74           0 : vl_api_trace_capture_packets_t_handler (vl_api_trace_capture_packets_t * mp)
      75             : {
      76           0 :   vlib_main_t *vm = vlib_get_main ();
      77           0 :   tracedump_main_t *tdmp = &tracedump_main;
      78           0 :   u32 add = clib_net_to_host_u32 (mp->max_packets);
      79           0 :   u32 node_index = clib_net_to_host_u32 (mp->node_index);
      80           0 :   u8 filter = mp->use_filter;
      81           0 :   u8 verbose = mp->verbose;
      82           0 :   u8 pre_clear = mp->pre_capture_clear;
      83             :   vl_api_trace_capture_packets_reply_t *rmp;
      84           0 :   int rv = 0;
      85             : 
      86           0 :   if (!vnet_trace_placeholder)
      87           0 :     vec_validate_aligned (vnet_trace_placeholder, 2048,
      88             :                           CLIB_CACHE_LINE_BYTES);
      89             : 
      90             :   vlib_node_t *node;
      91           0 :   node = vlib_get_node (vm, node_index);
      92           0 :   if (!node)
      93             :     {
      94           0 :       rv = VNET_API_ERROR_NO_SUCH_NODE;
      95           0 :       goto done;
      96             :     }
      97             : 
      98           0 :   if ((node->flags & VLIB_NODE_FLAG_TRACE_SUPPORTED) == 0)
      99             :     {
     100             :       /* FIXME: Make a new, better error like "UNSUPPORTED_NODE_OPERATION"? */
     101           0 :       rv = VNET_API_ERROR_NO_SUCH_NODE;
     102           0 :       goto done;
     103             :     }
     104             : 
     105           0 :   if (pre_clear)
     106           0 :     vlib_trace_stop_and_clear ();
     107             : 
     108           0 :   trace_update_capture_options (add, node_index, filter, verbose);
     109             : 
     110           0 : done:
     111           0 :   REPLY_MACRO (VL_API_TRACE_CAPTURE_PACKETS_REPLY);
     112             : }
     113             : 
     114             : 
     115             : static void
     116           0 : vl_api_trace_clear_capture_t_handler (vl_api_trace_clear_capture_t * mp)
     117             : {
     118             :   vl_api_trace_clear_capture_reply_t *rmp;
     119           0 :   tracedump_main_t *tdmp = &tracedump_main;
     120             : 
     121           0 :   vlib_trace_stop_and_clear ();
     122             : 
     123           0 :   int rv = 0;
     124           0 :   REPLY_MACRO (VL_API_TRACE_CLEAR_CAPTURE_REPLY);
     125             : }
     126             : 
     127             : 
     128             : 
     129             : static int
     130           0 : trace_cmp (void *a1, void *a2)
     131             : {
     132           0 :   vlib_trace_header_t **t1 = a1;
     133           0 :   vlib_trace_header_t **t2 = a2;
     134           0 :   i64 dt = t1[0]->time - t2[0]->time;
     135           0 :   return dt < 0 ? -1 : (dt > 0 ? +1 : 0);
     136             : }
     137             : 
     138             : static void
     139           0 : toss_client_cache (tracedump_main_t * tdmp, u32 client_index,
     140             :                    vlib_trace_header_t *** client_trace_cache)
     141             : {
     142             :   vlib_trace_header_t **th;
     143             :   int i;
     144             : 
     145             :   /* Across each vlib main... */
     146           0 :   for (i = 0; i < vec_len (client_trace_cache); i++)
     147             :     {
     148           0 :       th = client_trace_cache[i];
     149             :       /* Toss the thread's cached data */
     150           0 :       vec_free (th);
     151             :     }
     152             :   /* And toss the vector of threads */
     153           0 :   vec_free (client_trace_cache);
     154           0 :   tdmp->traces[client_index] = client_trace_cache;
     155           0 : }
     156             : 
     157             : static clib_error_t *
     158        1241 : tracedump_cache_reaper (u32 client_index)
     159             : {
     160        1241 :   tracedump_main_t *tdmp = &tracedump_main;
     161             :   vlib_trace_header_t ***client_trace_cache;
     162             : 
     163             :   /* Its likely that we won't have a cache entry */
     164        1241 :   if (client_index >= vec_len (tdmp->traces))
     165        1241 :     return 0;
     166             : 
     167           0 :   client_trace_cache = tdmp->traces[client_index];
     168           0 :   toss_client_cache (tdmp, client_index, client_trace_cache);
     169           0 :   return 0;
     170             : }
     171             : 
     172         575 : VL_MSG_API_REAPER_FUNCTION (tracedump_cache_reaper);
     173             : 
     174             : /* API message handler */
     175             : static void
     176           0 : vl_api_trace_dump_t_handler (vl_api_trace_dump_t * mp)
     177             : {
     178             :   vl_api_registration_t *rp;
     179             :   vl_api_trace_dump_reply_t *rmp;
     180             :   vl_api_trace_details_t *dmp;
     181           0 :   tracedump_main_t *tdmp = &tracedump_main;
     182             :   vlib_trace_header_t ***client_trace_cache, **th;
     183             :   int i, j;
     184             :   u32 client_index;
     185             :   u32 iterator_thread_id, iterator_position, max_records;
     186           0 :   i32 retval = VNET_API_ERROR_NO_SUCH_ENTRY;
     187           0 :   u32 last_thread_id = ~0, last_position = ~0;
     188           0 :   u8 last_done = 0;
     189           0 :   u8 last_more_this_thread = 0;
     190           0 :   u8 last_more_threads = 0;
     191           0 :   u8 *s = 0;
     192             : 
     193           0 :   rp = vl_api_client_index_to_registration (mp->client_index);
     194           0 :   if (rp == 0)
     195           0 :     return;
     196             : 
     197             :   /* Use the registration pool index... */
     198           0 :   client_index = rp->vl_api_registration_pool_index;
     199             : 
     200           0 :   vec_validate_init_empty (tdmp->traces, client_index, 0);
     201             : 
     202           0 :   client_trace_cache = tdmp->traces[client_index];
     203             : 
     204             :   /* Clear the per-client cache if requested */
     205           0 :   if (mp->clear_cache)
     206             :     {
     207           0 :       toss_client_cache (tdmp, client_index, client_trace_cache);
     208           0 :       client_trace_cache = 0;
     209             :     }
     210             : 
     211             :   /* Now, where were we? */
     212           0 :   iterator_thread_id = clib_net_to_host_u32 (mp->thread_id);
     213           0 :   iterator_position = clib_net_to_host_u32 (mp->position);
     214           0 :   max_records = clib_net_to_host_u32 (mp->max_records);
     215             : 
     216             :   /* Don't overflow the existing queue space for shared memory API clients. */
     217           0 :   if (rp->vl_input_queue)
     218             :     {
     219           0 :       svm_queue_t *q = rp->vl_input_queue;
     220           0 :       u32 queue_slots_available = q->maxsize - q->cursize;
     221           0 :       int chunk = (queue_slots_available > 0) ? queue_slots_available - 1 : 0;
     222           0 :       if (chunk < max_records)
     223           0 :         max_records = chunk;
     224             :     }
     225             : 
     226             :   /* Need a fresh cache for this client? */
     227           0 :   if (vec_len (client_trace_cache) == 0
     228           0 :       && (iterator_thread_id != ~0 || iterator_position != ~0))
     229             :     {
     230           0 :       vlib_worker_thread_barrier_sync (vlib_get_first_main ());
     231             : 
     232             :       /* Make a slot for each worker thread */
     233           0 :       vec_validate (client_trace_cache, vlib_get_n_threads () - 1);
     234           0 :       i = 0;
     235             : 
     236           0 :       foreach_vlib_main ()
     237             :         {
     238           0 :           vlib_trace_main_t *tm = &this_vlib_main->trace_main;
     239             : 
     240             :           /* Filter as directed */
     241           0 :           trace_apply_filter (this_vlib_main);
     242             : 
     243           0 :           pool_foreach (th, tm->trace_buffer_pool)
     244             :             {
     245           0 :               vec_add1 (client_trace_cache[i], th[0]);
     246             :             }
     247             : 
     248             :           /* Sort them by increasing time. */
     249           0 :           if (vec_len (client_trace_cache[i]))
     250           0 :             vec_sort_with_function (client_trace_cache[i], trace_cmp);
     251             : 
     252           0 :           i++;
     253             :         }
     254           0 :       vlib_worker_thread_barrier_release (vlib_get_first_main ());
     255             :     }
     256             : 
     257             :   /* Save the cache, one way or the other */
     258           0 :   tdmp->traces[client_index] = client_trace_cache;
     259             : 
     260           0 :   for (i = iterator_thread_id; i < vec_len (client_trace_cache); i++)
     261             :     {
     262           0 :       for (j = iterator_position; j < vec_len (client_trace_cache[i]); j++)
     263             :         {
     264           0 :           if (max_records == 0)
     265           0 :             break;
     266             : 
     267           0 :           retval = 0;
     268           0 :           th = &client_trace_cache[i][j];
     269             : 
     270           0 :           vec_reset_length (s);
     271             : 
     272           0 :           s =
     273           0 :             format (s, "%U", format_vlib_trace, vlib_get_first_main (), th[0]);
     274             : 
     275           0 :           dmp = vl_msg_api_alloc (sizeof (*dmp) + vec_len (s));
     276           0 :           dmp->_vl_msg_id =
     277           0 :             htons (VL_API_TRACE_DETAILS + (tdmp->msg_id_base));
     278           0 :           dmp->context = mp->context;
     279           0 :           last_thread_id = dmp->thread_id = ntohl (i);
     280           0 :           last_position = dmp->position = ntohl (j);
     281           0 :           vl_api_vec_to_api_string (s, &dmp->trace_data);
     282           0 :           dmp->packet_number = htonl (j);
     283           0 :           dmp->more_threads = 0;
     284           0 :           dmp->more_this_thread = 0;
     285             : 
     286             :           /* Last record in the batch? */
     287           0 :           if (max_records == 1)
     288             :             {
     289             :               /* More threads, but not more in this thread? */
     290           0 :               if (j == (vec_len (client_trace_cache[i]) - 1))
     291           0 :                 dmp->more_threads = 1;
     292             :               else
     293           0 :                 dmp->more_this_thread = 1;
     294             :             }
     295             :           /* Done, may or may not be at the end of a batch. */
     296           0 :           dmp->done = 0;
     297           0 :           if (i == (vec_len (client_trace_cache) - 1) &&
     298           0 :               j == (vec_len (client_trace_cache[i]) - 1))
     299             :             {
     300           0 :               last_done = dmp->done = 1;
     301           0 :               last_more_threads = dmp->more_threads = 0;
     302           0 :               last_more_this_thread = dmp->more_this_thread = 0;
     303           0 :               vl_api_send_msg (rp, (u8 *) dmp);
     304           0 :               goto doublebreak;
     305             :             }
     306           0 :           last_done = dmp->done;
     307           0 :           vl_api_send_msg (rp, (u8 *) dmp);
     308             : 
     309           0 :           max_records--;
     310             :         }
     311           0 :       iterator_position = 0;
     312             :     }
     313             : 
     314           0 : doublebreak:;
     315             : 
     316           0 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     317           0 :   rmp->_vl_msg_id = htons (VL_API_TRACE_DUMP_REPLY + (tdmp->msg_id_base));
     318           0 :   rmp->context = mp->context;
     319           0 :   rmp->retval = clib_host_to_net_u32 (retval);
     320           0 :   rmp->last_thread_id = last_thread_id;
     321           0 :   rmp->last_position = last_position;
     322           0 :   rmp->done = last_done;
     323           0 :   rmp->more_this_thread = last_more_this_thread;
     324           0 :   rmp->more_threads = last_more_threads;
     325             : 
     326             :   /* Tag cleanup flushes to make life easy for the client */
     327           0 :   if (iterator_thread_id == ~0 && iterator_position == ~0)
     328             :     {
     329           0 :       rmp->retval = 0;
     330           0 :       rmp->done = 1;
     331           0 :       rmp->flush_only = 1;
     332             :     }
     333           0 :   vl_api_send_msg (rp, (u8 *) rmp);
     334             : 
     335           0 :   vec_free (s);
     336             : }
     337             : 
     338             : /* API message handler */
     339             : static void
     340           0 : vl_api_trace_v2_dump_t_handler (vl_api_trace_v2_dump_t *mp)
     341             : {
     342             :   vl_api_registration_t *rp;
     343             :   vl_api_trace_v2_details_t *dmp;
     344           0 :   tracedump_main_t *tdmp = &tracedump_main;
     345             :   vlib_trace_header_t ***client_trace_cache, **th;
     346             :   int i, j;
     347             :   u32 client_index;
     348             :   u32 first_position, max, first_thread_id, last_thread_id;
     349           0 :   u32 n_threads = vlib_get_n_threads ();
     350           0 :   u8 *s = 0;
     351             : 
     352           0 :   rp = vl_api_client_index_to_registration (mp->client_index);
     353           0 :   if (rp == 0)
     354           0 :     return;
     355             : 
     356           0 :   client_index = rp->vl_api_registration_pool_index;
     357             : 
     358           0 :   vec_validate_init_empty (tdmp->traces, client_index, 0);
     359             : 
     360           0 :   client_trace_cache = tdmp->traces[client_index];
     361             : 
     362           0 :   if (mp->clear_cache)
     363             :     {
     364           0 :       toss_client_cache (tdmp, client_index, client_trace_cache);
     365           0 :       client_trace_cache = 0;
     366             :     }
     367             : 
     368             :   /* Now, where were we? */
     369           0 :   first_thread_id = last_thread_id = clib_net_to_host_u32 (mp->thread_id);
     370           0 :   first_position = clib_net_to_host_u32 (mp->position);
     371           0 :   max = clib_net_to_host_u32 (mp->max);
     372             : 
     373           0 :   if (first_thread_id == ~0)
     374             :     {
     375           0 :       first_thread_id = 0;
     376           0 :       last_thread_id = n_threads - 1;
     377             :     }
     378             : 
     379             :   /* Don't overflow the existing queue space for shared memory API clients. */
     380           0 :   if (rp->vl_input_queue)
     381             :     {
     382           0 :       svm_queue_t *q = rp->vl_input_queue;
     383           0 :       u32 queue_slots_available = q->maxsize - q->cursize;
     384           0 :       int chunk = (queue_slots_available > 0) ? queue_slots_available - 1 : 0;
     385             :       /* split available slots among requested threads */
     386           0 :       if (chunk < max * (last_thread_id - first_thread_id + 1))
     387           0 :         max = chunk / (last_thread_id - first_thread_id + 1);
     388             :     }
     389             : 
     390             :   /* Need a fresh cache for this client? */
     391           0 :   if (vec_len (client_trace_cache) == 0 && first_position != ~0)
     392             :     {
     393           0 :       vlib_worker_thread_barrier_sync (vlib_get_first_main ());
     394             : 
     395             :       /* Make a slot for each worker thread */
     396           0 :       vec_validate (client_trace_cache, n_threads - 1);
     397           0 :       i = 0;
     398             : 
     399           0 :       foreach_vlib_main ()
     400             :         {
     401           0 :           vlib_trace_main_t *tm = &this_vlib_main->trace_main;
     402             : 
     403             :           /* Filter as directed */
     404           0 :           trace_apply_filter (this_vlib_main);
     405             : 
     406           0 :           pool_foreach (th, tm->trace_buffer_pool)
     407             :             {
     408           0 :               vec_add1 (client_trace_cache[i], th[0]);
     409             :             }
     410             : 
     411             :           /* Sort them by increasing time. */
     412           0 :           if (vec_len (client_trace_cache[i]))
     413           0 :             vec_sort_with_function (client_trace_cache[i], trace_cmp);
     414             : 
     415           0 :           i++;
     416             :         }
     417           0 :       vlib_worker_thread_barrier_release (vlib_get_first_main ());
     418             :     }
     419             : 
     420             :   /* Save the cache, one way or the other */
     421           0 :   tdmp->traces[client_index] = client_trace_cache;
     422             : 
     423           0 :   for (i = first_thread_id;
     424           0 :        i <= last_thread_id && i < vec_len (client_trace_cache); i++)
     425             :     {
     426             :       // dump a number of 'max' packets per thead
     427           0 :       for (j = first_position;
     428           0 :            j < vec_len (client_trace_cache[i]) && j < first_position + max;
     429           0 :            j++)
     430             :         {
     431           0 :           th = &client_trace_cache[i][j];
     432             : 
     433           0 :           vec_reset_length (s);
     434             : 
     435           0 :           s =
     436           0 :             format (s, "%U", format_vlib_trace, vlib_get_first_main (), th[0]);
     437             : 
     438           0 :           dmp = vl_msg_api_alloc (sizeof (*dmp) + vec_len (s));
     439           0 :           dmp->_vl_msg_id =
     440           0 :             htons (VL_API_TRACE_V2_DETAILS + (tdmp->msg_id_base));
     441           0 :           dmp->context = mp->context;
     442           0 :           dmp->thread_id = ntohl (i);
     443           0 :           dmp->position = ntohl (j);
     444           0 :           dmp->more = j < vec_len (client_trace_cache[i]) - 1;
     445           0 :           vl_api_vec_to_api_string (s, &dmp->trace_data);
     446             : 
     447           0 :           vl_api_send_msg (rp, (u8 *) dmp);
     448             :         }
     449             :     }
     450             : 
     451           0 :   vec_free (s);
     452             : }
     453             : 
     454             : static void
     455           0 : vl_api_trace_clear_cache_t_handler (vl_api_trace_clear_cache_t *mp)
     456             : {
     457             :   vl_api_registration_t *rp;
     458           0 :   tracedump_main_t *tdmp = &tracedump_main;
     459             :   vlib_trace_header_t ***client_trace_cache;
     460             :   vl_api_trace_clear_cache_reply_t *rmp;
     461             :   u32 client_index;
     462             : 
     463           0 :   rp = vl_api_client_index_to_registration (mp->client_index);
     464           0 :   if (rp == 0)
     465           0 :     return;
     466             : 
     467           0 :   client_index = rp->vl_api_registration_pool_index;
     468           0 :   vec_validate_init_empty (tdmp->traces, client_index, 0);
     469           0 :   client_trace_cache = tdmp->traces[client_index];
     470           0 :   toss_client_cache (tdmp, client_index, client_trace_cache);
     471             : 
     472           0 :   int rv = 0;
     473           0 :   REPLY_MACRO (VL_API_TRACE_CLEAR_CACHE_REPLY);
     474             : }
     475             : 
     476             : static void
     477           0 : vl_api_trace_set_filter_function_t_handler (
     478             :   vl_api_trace_set_filter_function_t *mp)
     479             : {
     480             :   vl_api_trace_set_filter_function_reply_t *rmp;
     481           0 :   tracedump_main_t *tdmp = &tracedump_main;
     482           0 :   unformat_input_t input = { 0 };
     483             :   vlib_is_packet_traced_fn_t *f;
     484             :   char *filter_name;
     485           0 :   int rv = 0;
     486           0 :   filter_name = vl_api_from_api_to_new_c_string (&mp->filter_function_name);
     487           0 :   unformat_init_cstring (&input, filter_name);
     488           0 :   if (unformat (&input, "%U", unformat_vlib_trace_filter_function, &f) == 0)
     489             :     {
     490           0 :       rv = -1;
     491           0 :       goto done;
     492             :     }
     493           0 :   vlib_set_trace_filter_function (f);
     494           0 : done:
     495           0 :   unformat_free (&input);
     496           0 :   vec_free (filter_name);
     497           0 :   REPLY_MACRO (VL_API_TRACE_SET_FILTER_FUNCTION_REPLY);
     498             : }
     499             : 
     500             : static void
     501           0 : vl_api_trace_filter_function_dump_t_handler (
     502             :   vl_api_trace_filter_function_dump_t *mp)
     503             : {
     504             :   vl_api_registration_t *rp;
     505             :   vl_api_trace_filter_function_details_t *dmp;
     506           0 :   tracedump_main_t *tdmp = &tracedump_main;
     507           0 :   vlib_trace_filter_main_t *tfm = &vlib_trace_filter_main;
     508           0 :   vlib_trace_filter_function_registration_t *reg =
     509             :     tfm->trace_filter_registration;
     510           0 :   vlib_main_t *vm = vlib_get_main ();
     511           0 :   vlib_is_packet_traced_fn_t *current =
     512             :     vm->trace_main.current_trace_filter_function;
     513           0 :   rp = vl_api_client_index_to_registration (mp->client_index);
     514             : 
     515           0 :   if (rp == 0)
     516           0 :     return;
     517             : 
     518           0 :   while (reg)
     519             :     {
     520           0 :       dmp = vl_msg_api_alloc (sizeof (*dmp) + strlen (reg->name));
     521           0 :       dmp->_vl_msg_id =
     522           0 :         htons (VL_API_TRACE_FILTER_FUNCTION_DETAILS + (tdmp->msg_id_base));
     523           0 :       dmp->context = mp->context;
     524           0 :       vl_api_c_string_to_api_string (reg->name, &dmp->name);
     525           0 :       dmp->selected = current == reg->function;
     526           0 :       vl_api_send_msg (rp, (u8 *) dmp);
     527           0 :       reg = reg->next;
     528             :     }
     529             : }
     530             : 
     531             : /* API definitions */
     532             : #include <tracedump/tracedump.api.c>
     533             : 
     534             : static clib_error_t *
     535         575 : tracedump_init (vlib_main_t * vm)
     536             : {
     537         575 :   tracedump_main_t *tdmp = &tracedump_main;
     538         575 :   api_main_t *am = vlibapi_get_main ();
     539             : 
     540         575 :   clib_error_t *error = 0;
     541             : 
     542         575 :   tdmp->vlib_main = vm;
     543         575 :   tdmp->vnet_main = vnet_get_main ();
     544             : 
     545             :   /* Add our API messages to the global name_crc hash table */
     546         575 :   tdmp->msg_id_base = setup_message_id_table ();
     547             : 
     548         575 :   vl_api_set_msg_thread_safe (am, tdmp->msg_id_base + VL_API_TRACE_DUMP, 1);
     549         575 :   vl_api_set_msg_thread_safe (am, tdmp->msg_id_base + VL_API_TRACE_V2_DUMP, 1);
     550             : 
     551         575 :   return error;
     552             : }
     553             : 
     554        1151 : VLIB_INIT_FUNCTION (tracedump_init);
     555             : /* *INDENT-OFF* */
     556             : VLIB_PLUGIN_REGISTER () =
     557             : {
     558             :   .version = VPP_BUILD_VER,
     559             :   .description = "Streaming packet trace dump plugin",
     560             : };
     561             : /* *INDENT-ON* */
     562             : 
     563             : /*
     564             :  * fd.io coding-style-patch-verification: ON
     565             :  *
     566             :  * Local Variables:
     567             :  * eval: (c-set-style "gnu")
     568             :  * End:
     569             :  */

Generated by: LCOV version 1.14