More janitorial work
[vpp.git] / plugins / plugins / vcgn / spp_platform_trace_log.c
1 /*
2  *------------------------------------------------------------------
3  * spp_platform_trace_log.c 
4  *
5  * Copyright (c) 2008-2011, 2013 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *---------------------------------------------------------------------------
18  */
19
20 #include <vlib/vlib.h>
21 #include <stdio.h>
22 #include <vppinfra/vec.h>
23 #include <vppinfra/bitmap.h>
24 #include <vppinfra/hash.h>
25 #include <vppinfra/pool.h>
26 #include <vppinfra/clib.h>
27 #include <vlib/main.h>
28
29 #include "tcp_header_definitions.h"
30 #include "platform_common.h"
31 #include "spp_platform_trace_log.h"
32
33 #define WORD_SIZE sizeof(u32)
34
35 int temperature_read_blocked = 1;
36
37 spp_cnat_logger_tbl_t spp_cnat_logger_table[] =
38 {
39   { CNAT_ERROR_SUCCESS,
40     3,
41     0,
42     {"i-vrf",
43     "ipv4 addr",
44      "port"}
45   },
46   { CNAT_NO_CONFIG_ERROR,
47     3,
48     180,
49     {"i-vrf",
50     "ipv4 addr",
51      "port"}
52   },
53   { CNAT_NO_VRF_RUN_ERROR,
54     3,
55     180,
56     {"i-vrf",
57     "ipv4 addr",
58      "port"}
59   },
60   { CNAT_NO_POOL_FOR_ANY_ERROR,
61     3,
62     180,
63     {"i-vrf",
64     "ipv4 addr",
65      "port"}
66   },
67   { CNAT_NO_PORT_FOR_ANY_ERROR,
68     3,
69     60,
70     {"i-vrf",
71     "ipv4 addr",
72      "port"}
73   },
74   { CNAT_BAD_INUSE_ANY_ERROR,
75     3,
76     60,
77     {"i-vrf",
78     "ipv4 addr",
79      "port"}
80   },
81   { CNAT_NOT_FOUND_ANY_ERROR,
82     3,
83     60,
84     {"i-vrf",
85     "ipv4 addr",
86      "port"}
87   },
88   { CNAT_INV_PORT_FOR_DIRECT_ERROR,
89     3,
90     60,
91     {"i-vrf",
92     "ipv4 addr",
93      "port"}
94   },
95   { CNAT_BAD_INUSE_DIRECT_ERROR,
96     3,
97     1,
98     {"i-vrf",
99     "ipv4 addr",
100      "port"}
101   },
102   { CNAT_NOT_FOUND_DIRECT_ERROR,
103     3,
104     1,
105     {"i-vrf",
106     "ipv4 addr",
107      "port"}
108   },
109   { CNAT_OUT_OF_PORT_LIMIT_ERROR,
110     3,
111     60,
112     {"i-vrf",
113     "ipv4 addr",
114      "port"}
115   },
116   { CNAT_MAIN_DB_CREATE_ERROR, 
117     0,
118     30,
119     {""}
120   },
121   { CNAT_LOOKUP_ERROR,
122     1,
123     30,
124     {"Type"}
125   },
126   { CNAT_INDEX_MISMATCH_ERROR,
127     2,
128     30,
129     {"in2out_index",
130      "out2in_index"}
131   },
132   { CNAT_PACKET_DROP_ERROR,
133     3,
134     15,
135     {"i-vrf",
136     "ipv4 addr",
137      "port"}
138   },
139   { CNAT_INV_UNUSED_USR_INDEX,
140     1,
141     10,
142     {"invalid/unused user index"}
143   },
144   { CNAT_INVALID_VRFMAP_INDEX,
145     0,
146     60,
147     {""}
148   },
149   { CNAT_USER_OUT_OF_PORTS,
150     2,
151     1800,
152     {"i-vrf",
153      "ipv4 addr"}
154   },
155   { CNAT_EXT_PORT_THRESH_EXCEEDED,
156     2,
157     180,
158     {"i-vrf",
159      "ipv4 address"}
160   },
161   { CNAT_EXT_PORT_THRESH_NORMAL,
162     2,
163     180,
164     {"vrf",
165      "ipv4 address"}
166   },
167   { CNAT_NO_EXT_PORT_AVAILABLE,
168     0,
169     1,
170     {"",}
171   },
172   { CNAT_SESSION_THRESH_EXCEEDED,
173     2,
174     1800, 
175     {"vrf",
176      "ipv4 address"}
177   },
178   { CNAT_SESSION_THRESH_NORMAL,
179     2,
180     30, /* changed to 30 */
181     {"vrf",
182      "ipv4 address"}
183   },
184   { WQE_ALLOCATION_ERROR,
185     0,
186     180, /* changed to 180 */
187     {""}
188   },
189   { ERROR_PKT_DROPPED,
190     2,
191     60, /* changed to 60 */
192     {"spi-port",
193      "error-code"}
194   },
195   { SYSMGR_PD_KEY_CREATION_ERROR,
196     0,
197     30,
198     {""}
199   },
200   { SYSMGR_PD_SHMEM_ID_ERROR,
201     0,
202     1,
203     {""}
204   },
205   { SYSMGR_PD_SHMEM_ATTACH_ERROR,
206     0,
207     1,
208     {""}
209   },
210   { OCTEON_CKHUM_SKIPPED,
211     2,
212     60, /* changed to 60 */
213     {"version",
214      "protocol"}
215   },
216   { PK0_SEND_STATUS,
217     1,
218     15,
219     {"status"}
220   },
221   { CMD_BUF_ALLOC_ERR,
222     0,
223     60,
224     {""}
225   },
226   { SPP_CTX_ALLOC_FAILED,
227     1,
228     300, /* every 5 min  */
229     {"node"}
230   },
231   { SPP_MAX_DISPATCH_REACHED,
232     1,
233     60,
234     {"node"}
235   },
236   { HA_SIGCHILD_RECV,
237     3,
238     1,
239     {"pid",
240     "uid",
241      "signal",}
242   },
243   { SIGACTION_ERR,
244     0,
245     1,
246     {""}
247   },
248   { HA_INVALID_SEQ_OR_CONFIG_OR_TYPE,
249     2,
250     10,
251     {"seq-id or config option",
252      "Type"}
253   },
254   { NODE_CREATION_ERROR,
255     1,
256     1,
257     {"node"}
258   },
259
260   { CNAT_CLI_INVALID_INPUT,
261       4,
262       0,
263     {"Error Type",
264       "Passed",
265       "Expected",
266      "Type"}
267   },
268   { CNAT_DUMMY_HANDLER_HIT,
269       1,
270       0,
271     {"Handler"}
272   },
273   { CNAT_CONFIG_ERROR,
274       5,
275       0,
276     {"Sub code",
277       "Param 1",
278       "Param 2",
279       "Param 3",
280      "Param 4"}
281   },
282   { CNAT_NFV9_ERROR,
283       1,
284       180, /* changed to 180 */
285     {"Sub code"}
286   },
287   { CNAT_CMVX_TWSI_READ_WRITE_FAIL,
288      3,
289      180,
290     {"Operation",
291      "Location",
292      "Data"}
293   },
294   { CNAT_TEMP_SENSOR_TIMEOUT,
295       0,
296       180,
297     {""}
298   },
299   { CNAT_TEMP_SENSOR_DATA_MISMATCH,
300       2,
301       180,
302     {"Actual",
303      "Expected"}
304   },
305   { CNAT_TEMP_SENSOR_CONFIG_FAILED,
306       1,
307       180,
308     {"Glik"}
309   },
310   { HA_APP_NOT_RESPONDING,
311       2,
312       180,
313     {"CPU",
314      "Core"}
315   },
316   { HA_DATA_PATH_TEST_FAILED,
317       0,
318       30,
319     {""}
320   },
321   { CNAT_WRONG_PORT_ALLOC_TYPE,
322       3,
323       60,
324     {"i-vrf",
325       "ipv4 addr",
326      "port"}
327   },
328   { CNAT_NEW_PORT_ALLOC_ERROR,
329       3,
330       60,
331     {"i-vrf",
332       "ipv4 addr",
333      "port"}
334   },
335   { CNAT_INVALID_INDEX_TO_FREE_PORT,
336       0,
337       60,
338     {""}
339   },
340   { CNAT_DELETE_DB_ENTRY_NO_PORTMAP,
341       0,
342       60,
343     {""}
344   },
345   { CNAT_MAIN_DB_LIMIT_ERROR,
346       0,
347       180,
348     {""}
349   },
350   { CNAT_USER_DB_LIMIT_ERROR,
351       0,
352       180,
353     {""}
354   },
355   { CNAT_FRAG_DB_ERROR,
356       1,
357       180,
358     {"Type"}
359   },
360
361   { DROP_PKT_DUMP,
362     0,
363     20,
364     {""}
365   }
366 };
367
368 #define LOG_TABLE_MAX_ENTRIES \
369    (sizeof(spp_cnat_logger_table)/sizeof(spp_cnat_logger_table[0]))
370
371 u32 error_code_timestamps[LOG_TABLE_MAX_ENTRIES];
372 spp_timer_t sensor_timer;
373 spp_trace_log_global_info_t spp_trace_log_global_info;
374 spp_global_counters_t spp_global_counters;
375
376 /*
377  * Logging information structures
378  */
379 spp_trace_log_info_t spp_default_trace_log_info;
380 spp_trace_log_info_t *spp_trace_log_info_pool;
381
382 #ifdef TOBE_PORTED
383 /*
384  * The following 2 functions are temporary hacks until
385  * we have RTC support from the PD nodes
386  */
387 inline
388 u32 spp_trace_log_get_sys_up_time_in_ms (void)
389 {
390     spp_node_main_vector_t *nmv;
391     u32 sys_up_time;
392
393     nmv = spp_get_node_main_vectorized_inline();
394                     
395     sys_up_time = (u32) (nmv->ticks / nmv->ticks_per_ms);
396
397     return (sys_up_time);
398 }
399
400 u32 spp_trace_log_get_unix_time_in_seconds (void)
401 {
402     spp_node_main_vector_t *nmv;
403     u32 unix_time;
404
405     nmv = spp_get_node_main_vectorized_inline();
406                     
407     unix_time = (u32) (nmv->ticks / nmv->ticks_per_second);
408
409     return (unix_time);
410 }
411
412 /*
413  * edt: * * spp_trace_log_send_queued_pkt
414  *
415  * Tries to send a logging pkt that has been queued earlier
416  * because it could not be sent due to downstream constipation
417  *
418  * Argument: spp_trace_log_info_t *trace_logging_info
419  * structure that contains the packet context
420  */
421 inline
422 void spp_trace_log_send_queued_pkt (spp_trace_log_info_t *trace_logging_info)
423 {
424     spp_node_t                  *output_node;
425
426     output_node = spp_get_nodes() + 
427         spp_trace_log_global_info.spp_trace_log_disp_node_index;
428
429     if (PREDICT_TRUE(output_node->sf.nused < SPP_MAXDISPATCH)) {
430         /*
431          * Move the logging context to output node
432          */
433         spp_dispatch_make_node_runnable(output_node);
434         output_node->sf.ctxs[output_node->sf.nused++] = 
435             trace_logging_info->queued_logging_context;
436
437         /*
438          * Context has been queued, it will be freed after the pkt
439          * is sent.  Clear this from the logging_context_info structure
440          */
441             trace_logging_info->queued_logging_context = NULL;
442
443     } else {
444             /*
445              * Can't do much, just return, may be we can send it later
446              */
447         spp_global_counters.spp_trace_log_downstream_constipation_count++;
448     }
449 }
450
451 /*
452  * edt: * * spp_trace_log_send_pkt
453  *
454  * Tries to send a logging pkt.  If the packet cannot be sent
455  * because of rewrite_output node cannot process it, queue
456  * it temporarily and try to send it later.
457  *
458  * Argument: spp_trace_log_info_t *trace_logging_info
459  * structure that contains the packet context
460  */
461 inline
462 void spp_trace_log_send_pkt (spp_trace_log_info_t *trace_logging_info)
463 {
464     spp_node_t                  *output_node;
465
466
467     output_node = spp_get_nodes() + 
468         spp_trace_log_global_info.spp_trace_log_disp_node_index;
469
470     if (PREDICT_TRUE(output_node->sf.nused < SPP_MAXDISPATCH)) {
471         /*
472          * Move the logging context to output node
473          */
474         spp_dispatch_make_node_runnable(output_node);
475         output_node->sf.ctxs[output_node->sf.nused++] = 
476             trace_logging_info->current_logging_context;
477
478     } else {
479         /*
480              * Queue the context into the logging_info structure,
481              * We will try to send it later.  Currently, we will
482          * restrict to only one context queued.
483              */
484         spp_global_counters.spp_trace_log_downstream_constipation_count++;
485
486             /*
487              * Attach the current logging context which is full to the
488              * queued context list in trace_logging_info structure
489              */
490             trace_logging_info->queued_logging_context =
491                     trace_logging_info->current_logging_context;
492
493             /*
494              * Whether the context is queued or not, set the current context index
495              * to EMPTY, as the earlier context can no more be used to send
496              * more logging records.
497              */
498     }
499
500     trace_logging_info->current_logging_context = NULL;
501 }
502
503 /*
504  * edt: * * spp_trace_log_send_pkt_always_success
505  *
506  * Tries to send a logging pkt.  This cannot fail due to downstream
507  * constipation because we have already checked if the rewrite_output
508  * node can accept it.
509  *
510  * Argument: spp_trace_log_info_t *trace_logging_info
511  * structure that contains the packet context
512  *
513  * Argument: spp_node_t *output_node
514  * spp_node_t structure for rewrite_output node
515  */
516 inline
517 void spp_trace_log_send_pkt_always_success (
518                          spp_trace_log_info_t *trace_logging_info,
519                          spp_node_t               *output_node)
520 {
521     /*
522      * At this point we either have a current or queued logging context
523      */
524     if (PREDICT_TRUE(trace_logging_info->current_logging_context != NULL)) { 
525
526         output_node->sf.ctxs[output_node->sf.nused++] = 
527             trace_logging_info->current_logging_context;
528
529         trace_logging_info->current_logging_context = NULL;
530     } else {
531         /*
532          * For queued logging context
533              */
534             output_node->sf.ctxs[output_node->sf.nused++] = 
535                  trace_logging_info->queued_logging_context;
536
537             trace_logging_info->queued_logging_context = NULL;
538     }
539
540     /*
541      * Move the logging context to output node
542      */
543     spp_dispatch_make_node_runnable(output_node);
544
545 }
546
547 /*
548  * edt: * * spp_create_trace_log_context
549  *
550  * Tries to create a logging context with packet buffer
551  * to send a new logging packet
552  *
553  * Argument: spp_trace_log_info_t *trace_logging_info
554  * structure that contains the nfv9 logging info and will store
555  * the packet context as well.
556  */
557 inline
558 void spp_create_trace_log_context (
559                               spp_trace_log_info_t *trace_logging_info)
560 {
561     spp_ctx_t *ctx;
562
563     /*
564      * If queued_logging_context_index is non-EMPTY, we already have a logging
565      * packet queued to be sent.  First try sending this before allocating
566      * a new context.  We can have only one active packet context per
567      * trace_logging_info structure
568      */
569     if (PREDICT_FALSE(trace_logging_info->queued_logging_context != NULL)) {
570         spp_trace_log_send_queued_pkt(trace_logging_info);
571         /*
572          * If we cannot still send the queued pkt, just return 
573          * Downstream Constipation count would have increased anyway
574          */
575         if (trace_logging_info->queued_logging_context != NULL) {
576                 spp_global_counters.spp_trace_log_context_creation_deferred_count++;
577                 return;
578         }
579     }
580
581
582     /*
583      * No context can be allocated, return silently
584      * calling routine will handle updating the error counters
585      */
586     if (spp_ctx_alloc(&ctx, 1) < 1) {
587         spp_global_counters.spp_trace_log_context_creation_fail_count++;
588             return;
589     }
590
591     trace_logging_info->current_logging_context = ctx;
592     trace_logging_info->pkt_length = 0;
593
594     trace_logging_info->current_logging_context_timestamp =
595                        spp_trace_log_get_sys_up_time_in_ms();
596
597     ctx->flags = SPP_CTX_END_OF_PACKET;
598     ctx->ru.tx.from_node = NODE_TRACE_BACKUP;
599     ctx->ru.tx.dst_ip_port_idx = EXT_TRACE_BACKUP_INDEX;
600     ctx->next_ctx_this_packet = (spp_ctx_t*) SPP_CTX_NO_NEXT_CTX;
601     ctx->current_header = &ctx->packet_data[SPP_TRACE_LOG_HDR_OFFSET];
602     ctx->current_length = 0;
603
604     trace_logging_info->log_record = 0;
605     trace_logging_info->total_record_count = 0;
606     trace_logging_info->next_data_ptr = 
607         (u8 *) &ctx->packet_data[SPP_TRACE_LOG_HDR_OFFSET];
608
609 }
610
611 /*
612  * edt: * * spp_trace_log_add_record_create
613  *
614  * Tries to create an add record to the NFV9 packet
615  *
616  * Argument: spp_trace_log_info_t *trace_logging_info
617  * structure that contains the nfv9 logging info and will store
618  * the packet context as well.
619  */
620 inline
621 void spp_trace_log_add_record_create (spp_trace_log_info_t *trace_logging_info)
622 {
623
624     trace_logging_info->log_header =
625     (spp_trace_log_hdr_t *) (trace_logging_info->next_data_ptr);
626
627     /*
628      * Initialize the number of traces recorded
629      */
630     trace_logging_info->log_header->num_traces =
631     spp_host_to_net_byte_order_32(0);
632
633
634     trace_logging_info->log_record  =
635     (spp_trace_log_t *) (trace_logging_info->log_header + 1);
636
637     /*
638      * Update the length of the total pkt 
639      */
640     trace_logging_info->pkt_length +=
641         SPP_LOG_TRACE_HEADER_LENGTH; 
642
643     /*
644      * Set the data pointer beyond the trace header field
645      */
646     trace_logging_info->next_data_ptr =
647         (u8 *) (trace_logging_info->log_header + 1);
648
649 }
650
651 /*
652  * edt: * * spp_trace_logger
653  *
654  * Tries to log  spp/cnat event/errors
655  *
656  * Argument: u8 *error_code
657  *  Error code passed
658  *
659  * Argument: optional arguments
660  */
661 void spp_trace_logger (u16 error_code, u16 num_args, u32 *arg)
662 {
663     spp_trace_log_info_t *trace_logging_info = 0; 
664     u8 i;
665
666     trace_logging_info = 
667         spp_trace_log_info_pool + 
668         spp_trace_log_global_info.spp_log_pool_index[SPP_LOG_LTRACE];
669
670     if (PREDICT_FALSE(trace_logging_info->current_logging_context == NULL)) {
671         spp_create_trace_log_context(trace_logging_info);
672
673             /*
674              * If still empty, return after increasing the count
675              */
676             if (PREDICT_FALSE(trace_logging_info->current_logging_context == NULL)) {
677                 return;
678             }
679     }
680
681     if (PREDICT_FALSE(trace_logging_info->log_record == NULL)) {
682         spp_trace_log_add_record_create(trace_logging_info);
683     }
684
685     /*
686      * We should definitely have add_record now, no need to sanitize
687      */
688     trace_logging_info->log_record->error_code = 
689                     spp_host_to_net_byte_order_16(error_code);
690     trace_logging_info->log_record->num_args = 
691                     spp_host_to_net_byte_order_16(num_args);
692
693     for (i = 0; i < num_args; i++) {
694         trace_logging_info->log_record->arg[i] = 
695                 spp_host_to_net_byte_order_32(*(arg + i));
696     }
697
698     trace_logging_info->pkt_length += SPP_TRACE_LOG_RECORD_LENGTH + WORD_SIZE*num_args;
699     trace_logging_info->current_logging_context->current_length =
700                   trace_logging_info->pkt_length;
701     trace_logging_info->total_record_count += 1;
702
703     trace_logging_info->next_data_ptr =
704         (u8 *) (trace_logging_info->next_data_ptr + WORD_SIZE + WORD_SIZE*num_args);
705
706     trace_logging_info->log_record = 
707            (spp_trace_log_t *) (trace_logging_info->next_data_ptr);
708
709     /*
710      * Initialize the number of traces recorded
711      */
712     trace_logging_info->log_header->num_traces =
713              spp_host_to_net_byte_order_32(trace_logging_info->total_record_count);
714
715
716
717     /*
718      * If we have exceeded the packet length, let us send the
719      * packet now.  There is buffer of additional bytes beyond
720      * max_pkt_length to ensure that the last add/delete record
721      * can be stored safely.
722      */
723     if (trace_logging_info->pkt_length > 
724             trace_logging_info->max_length_minus_max_record_size) {
725             spp_trace_log_send_pkt(trace_logging_info);
726     }
727 }
728
729
730 /*
731  * edt: * * spp_trace_log_timer_handler
732  *
733  * Timer handler for sending any pending NFV9 record
734  *
735  * Argument: spp_timer_t * timer_p
736  * Timer handler structure
737  */
738 inline 
739 void spp_trace_log_timer_handler (spp_timer_t * timer_p)
740 {
741     spp_node_t *output_node;
742     spp_trace_log_info_t *trace_logging_info = 0;
743     u32 current_timestamp = spp_trace_log_get_sys_up_time_in_ms();
744     i16 sf_nused;
745     
746     output_node = spp_get_nodes() + 
747                       spp_trace_log_global_info.spp_trace_log_disp_node_index;
748
749     sf_nused = output_node->sf.nused;
750
751     pool_foreach (trace_logging_info, spp_trace_log_info_pool, ({
752         /*
753          * Check if no more logging contexts can be queued
754          */
755             if (PREDICT_FALSE(sf_nused >= SPP_MAXDISPATCH)) {
756                 break;
757             }
758
759             /*
760              * If there is a current logging context and timestamp
761              * indicates it is pending for long, send it out
762              * Also if there is a queued context send it out as well
763              */
764         if (trace_logging_info->queued_logging_context ||
765             (trace_logging_info->current_logging_context &&
766                 (current_timestamp - 
767                  trace_logging_info->current_logging_context_timestamp) 
768                                                                 > 1000)) {
769             spp_trace_log_send_pkt_always_success(trace_logging_info,
770                                                     output_node);
771             sf_nused++;
772         }
773     }));
774
775     timer_p->expires =
776         spp_timer_in_n_ms_inline(1000); /* every 1 sec */
777     spp_timer_start(timer_p);
778
779 }
780 inline
781 void spp_sensor_timer_handler (spp_timer_t * timer_p)
782 {
783 #ifdef TARGET_RODDICK
784     if (!temperature_read_blocked) {
785         Init_temperature_sensors();
786         read_octeon_sensors(TEMPERATURE_SENSOR_QUIET_MODE);
787     }
788
789     timer_p->expires =
790                 spp_timer_in_n_ms_inline(60000); /* every 1 sec */
791     spp_timer_start(timer_p);
792
793 #endif
794 }
795 void init_trace_log_buf_pool (void)
796 {   
797     spp_trace_log_info_t *my_spp_log_info;
798     u8            found;
799     spp_log_type_t log_type;
800
801     /* 
802      * Init SPP logging info as needed, this will be done only once
803      */
804     spp_trace_log_init();
805
806     found = 0;
807
808     for (log_type = SPP_LOG_LTRACE; log_type < SPP_LOG_MAX; log_type++ ) {
809         /* Do we already have a map for this log type? */
810         pool_foreach (my_spp_log_info, spp_trace_log_info_pool, ({
811             if (my_spp_log_info->log_type == log_type) {
812                 found = 1;
813                 break;
814             }
815         }));
816
817         /*
818          * Entry not present
819          */
820         if (!found) {
821             pool_get(spp_trace_log_info_pool, my_spp_log_info);
822             memset(my_spp_log_info, 0, sizeof(*my_spp_log_info));
823
824             /*
825              * Make the current and head logging context indeices as EMPTY.
826              * When first logging happens, these get set correctly
827              */
828             my_spp_log_info->current_logging_context = NULL;
829             my_spp_log_info->queued_logging_context  = NULL;
830
831             my_spp_log_info->log_type = log_type;
832             my_spp_log_info->max_length_minus_max_record_size =
833                                 SPP_TRACE_LOG_MAX_PKT_LENGTH;
834
835             spp_trace_log_global_info.spp_log_pool_index[log_type] = 
836                            my_spp_log_info - spp_trace_log_info_pool;
837         }
838
839     }
840
841     return;
842 }
843
844
845 /*
846  * one time function
847  * has to be called at the init time
848  */
849 void spp_trace_log_init (void)
850 {
851     if (!spp_trace_log_global_info.spp_trace_log_init_done) {
852
853 #ifdef TARGET_RODDICK
854             spp_trace_log_global_info.spp_trace_log_disp_node_index =
855                  spp_lookup_node_index("roddick_infra_l3_tx");
856 #elif defined(TARGET_BOOSTER)
857             spp_trace_log_global_info.spp_trace_log_disp_node_index =
858                  spp_lookup_node_index("booster_infra_l3_tx");
859 #endif
860             ASSERT(spp_trace_log_global_info.spp_trace_log_disp_node_index != (u16)~0);
861
862             spp_trace_log_global_info.log_timer.cb_index = 
863             spp_timer_register_callback(spp_trace_log_timer_handler);
864             spp_trace_log_global_info.log_timer.expires = 
865                  spp_timer_in_n_ms_inline(1000); /* every 1 sec */
866             spp_timer_start(&spp_trace_log_global_info.log_timer);
867
868         if (!my_core_id) {
869             sensor_timer.cb_index =
870                     spp_timer_register_callback(spp_sensor_timer_handler);
871             sensor_timer.expires =
872                     spp_timer_in_n_ms_inline(60000); /* every 1 sec */
873             spp_timer_start(&sensor_timer);
874         }
875
876             spp_trace_log_global_info.spp_trace_log_init_done = 1;
877
878         /*
879          *  Set MSC ip_addr, port values
880          */
881 #ifdef TARGET_RODDICK
882         dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].ipv4_address =
883                                         vpp_boot_params.msc_ip_address;
884         switch(vpp_boot_params.octeon_number) {
885             case 0:
886                     dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
887                     break;
888             case 1:
889                     dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
890                     break;
891             case 2:
892                     dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
893                     break;
894             case 3:
895                     dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
896                     break;
897         }
898 #else
899         dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].ipv4_address = 0x01020304;
900         dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
901 #endif
902
903     }
904 }
905
906 void spp_printf (u16 error_code, u16 num_args, u32 *arg)
907 {
908     u32 current_timestamp;
909     spp_node_main_vector_t *nmv;
910
911     if (PREDICT_FALSE(error_code >= LOG_TABLE_MAX_ENTRIES))
912     {
913        /*  printf("Error code invalid %d, %d, %d, %d\n",
914             error_code, LOG_TABLE_MAX_ENTRIES,
915             sizeof(spp_cnat_logger_table), sizeof(spp_cnat_logger_table[0]));
916             */
917         return; /* Should not happen */
918     }
919
920     nmv = spp_get_node_main_vectorized_inline();
921     current_timestamp = nmv->ticks / nmv->ticks_per_second;
922
923     /* Check if any further hashing is required */
924
925     if (PREDICT_FALSE(error_code == DUMP_PKT_IDX)) {
926 #ifdef TARGET_RODDICK || defined(TARGET_BOOSTER)
927         spp_trace_logger(error_code, num_args, arg);
928 #else
929         u8 j ;
930
931         printf("PKT DUMP :: ");
932         for (j = 0 ; j < num_args; j++) {
933             printf("0x%x ", arg[j]);
934             if (j == (num_args - 1)) {
935                 printf("\n");
936             }
937         }
938 #endif
939     } else if (PREDICT_TRUE((current_timestamp - error_code_timestamps[error_code]) >=  
940                spp_cnat_logger_table[error_code].rate_limit_time)) {
941         /* update timestamp */
942         error_code_timestamps[error_code] = current_timestamp;
943
944 #ifdef TARGET_RODDICK || defined(TARGET_BOOSTER)
945         spp_trace_logger(error_code, num_args, arg);     
946 #else
947         u8 j ;
948    
949         for (j = 0 ; j < num_args; j++) {
950             printf("%s: %d ", spp_cnat_logger_table[error_code].param_name[j], arg[j]);
951             if (j == (num_args - 1)) {
952                 printf("\n");
953             }
954         }
955 #endif
956     }
957 }
958     
959 #else /* TOBE_PORTEED */
960 void spp_trace_logger(u16 error_code, u16 num_args, u32 *arg)
961 {
962   /* To be filled */
963 }
964
965 void spp_trace_log_init(void)
966 {
967   /* To be filled */
968 }
969
970 void init_trace_log_buf_pool(void)
971 {
972   /* To be filled */
973 }
974
975 void spp_printf(u16 error_code, u16 num_args, u32 *arg)
976 {
977   /* To be filled */
978 }
979
980 inline u32 spp_trace_log_get_unix_time_in_seconds (void)
981 {
982     vlib_main_t  *vlib_main;
983
984     vlib_main = vlib_get_main();
985     return(vlib_time_now((vlib_main_t *) vlib_main));
986 }
987
988 #endif /* TOBE_PORTED */
989