
directory and GNU autotools setup. Change-Id: I6c59d1297389c9413db0c0b9bdf3b759080bf1b8 Signed-off-by: Ole Troan <ot@cisco.com>
990 lines
24 KiB
C
990 lines
24 KiB
C
/*
|
|
*------------------------------------------------------------------
|
|
* spp_platform_trace_log.c
|
|
*
|
|
* Copyright (c) 2008-2011, 2013 Cisco and/or its affiliates.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <vlib/vlib.h>
|
|
#include <stdio.h>
|
|
#include <vppinfra/vec.h>
|
|
#include <vppinfra/bitmap.h>
|
|
#include <vppinfra/hash.h>
|
|
#include <vppinfra/pool.h>
|
|
#include <vppinfra/clib.h>
|
|
#include <vlib/main.h>
|
|
|
|
#include "tcp_header_definitions.h"
|
|
#include "platform_common.h"
|
|
#include "spp_platform_trace_log.h"
|
|
|
|
#define WORD_SIZE sizeof(u32)
|
|
|
|
int temperature_read_blocked = 1;
|
|
|
|
spp_cnat_logger_tbl_t spp_cnat_logger_table[] =
|
|
{
|
|
{ CNAT_ERROR_SUCCESS,
|
|
3,
|
|
0,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_NO_CONFIG_ERROR,
|
|
3,
|
|
180,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_NO_VRF_RUN_ERROR,
|
|
3,
|
|
180,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_NO_POOL_FOR_ANY_ERROR,
|
|
3,
|
|
180,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_NO_PORT_FOR_ANY_ERROR,
|
|
3,
|
|
60,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_BAD_INUSE_ANY_ERROR,
|
|
3,
|
|
60,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_NOT_FOUND_ANY_ERROR,
|
|
3,
|
|
60,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_INV_PORT_FOR_DIRECT_ERROR,
|
|
3,
|
|
60,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_BAD_INUSE_DIRECT_ERROR,
|
|
3,
|
|
1,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_NOT_FOUND_DIRECT_ERROR,
|
|
3,
|
|
1,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_OUT_OF_PORT_LIMIT_ERROR,
|
|
3,
|
|
60,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_MAIN_DB_CREATE_ERROR,
|
|
0,
|
|
30,
|
|
{""}
|
|
},
|
|
{ CNAT_LOOKUP_ERROR,
|
|
1,
|
|
30,
|
|
{"Type"}
|
|
},
|
|
{ CNAT_INDEX_MISMATCH_ERROR,
|
|
2,
|
|
30,
|
|
{"in2out_index",
|
|
"out2in_index"}
|
|
},
|
|
{ CNAT_PACKET_DROP_ERROR,
|
|
3,
|
|
15,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_INV_UNUSED_USR_INDEX,
|
|
1,
|
|
10,
|
|
{"invalid/unused user index"}
|
|
},
|
|
{ CNAT_INVALID_VRFMAP_INDEX,
|
|
0,
|
|
60,
|
|
{""}
|
|
},
|
|
{ CNAT_USER_OUT_OF_PORTS,
|
|
2,
|
|
1800,
|
|
{"i-vrf",
|
|
"ipv4 addr"}
|
|
},
|
|
{ CNAT_EXT_PORT_THRESH_EXCEEDED,
|
|
2,
|
|
180,
|
|
{"i-vrf",
|
|
"ipv4 address"}
|
|
},
|
|
{ CNAT_EXT_PORT_THRESH_NORMAL,
|
|
2,
|
|
180,
|
|
{"vrf",
|
|
"ipv4 address"}
|
|
},
|
|
{ CNAT_NO_EXT_PORT_AVAILABLE,
|
|
0,
|
|
1,
|
|
{"",}
|
|
},
|
|
{ CNAT_SESSION_THRESH_EXCEEDED,
|
|
2,
|
|
1800,
|
|
{"vrf",
|
|
"ipv4 address"}
|
|
},
|
|
{ CNAT_SESSION_THRESH_NORMAL,
|
|
2,
|
|
30, /* changed to 30 */
|
|
{"vrf",
|
|
"ipv4 address"}
|
|
},
|
|
{ WQE_ALLOCATION_ERROR,
|
|
0,
|
|
180, /* changed to 180 */
|
|
{""}
|
|
},
|
|
{ ERROR_PKT_DROPPED,
|
|
2,
|
|
60, /* changed to 60 */
|
|
{"spi-port",
|
|
"error-code"}
|
|
},
|
|
{ SYSMGR_PD_KEY_CREATION_ERROR,
|
|
0,
|
|
30,
|
|
{""}
|
|
},
|
|
{ SYSMGR_PD_SHMEM_ID_ERROR,
|
|
0,
|
|
1,
|
|
{""}
|
|
},
|
|
{ SYSMGR_PD_SHMEM_ATTACH_ERROR,
|
|
0,
|
|
1,
|
|
{""}
|
|
},
|
|
{ OCTEON_CKHUM_SKIPPED,
|
|
2,
|
|
60, /* changed to 60 */
|
|
{"version",
|
|
"protocol"}
|
|
},
|
|
{ PK0_SEND_STATUS,
|
|
1,
|
|
15,
|
|
{"status"}
|
|
},
|
|
{ CMD_BUF_ALLOC_ERR,
|
|
0,
|
|
60,
|
|
{""}
|
|
},
|
|
{ SPP_CTX_ALLOC_FAILED,
|
|
1,
|
|
300, /* every 5 min */
|
|
{"node"}
|
|
},
|
|
{ SPP_MAX_DISPATCH_REACHED,
|
|
1,
|
|
60,
|
|
{"node"}
|
|
},
|
|
{ HA_SIGCHILD_RECV,
|
|
3,
|
|
1,
|
|
{"pid",
|
|
"uid",
|
|
"signal",}
|
|
},
|
|
{ SIGACTION_ERR,
|
|
0,
|
|
1,
|
|
{""}
|
|
},
|
|
{ HA_INVALID_SEQ_OR_CONFIG_OR_TYPE,
|
|
2,
|
|
10,
|
|
{"seq-id or config option",
|
|
"Type"}
|
|
},
|
|
{ NODE_CREATION_ERROR,
|
|
1,
|
|
1,
|
|
{"node"}
|
|
},
|
|
|
|
{ CNAT_CLI_INVALID_INPUT,
|
|
4,
|
|
0,
|
|
{"Error Type",
|
|
"Passed",
|
|
"Expected",
|
|
"Type"}
|
|
},
|
|
{ CNAT_DUMMY_HANDLER_HIT,
|
|
1,
|
|
0,
|
|
{"Handler"}
|
|
},
|
|
{ CNAT_CONFIG_ERROR,
|
|
5,
|
|
0,
|
|
{"Sub code",
|
|
"Param 1",
|
|
"Param 2",
|
|
"Param 3",
|
|
"Param 4"}
|
|
},
|
|
{ CNAT_NFV9_ERROR,
|
|
1,
|
|
180, /* changed to 180 */
|
|
{"Sub code"}
|
|
},
|
|
{ CNAT_CMVX_TWSI_READ_WRITE_FAIL,
|
|
3,
|
|
180,
|
|
{"Operation",
|
|
"Location",
|
|
"Data"}
|
|
},
|
|
{ CNAT_TEMP_SENSOR_TIMEOUT,
|
|
0,
|
|
180,
|
|
{""}
|
|
},
|
|
{ CNAT_TEMP_SENSOR_DATA_MISMATCH,
|
|
2,
|
|
180,
|
|
{"Actual",
|
|
"Expected"}
|
|
},
|
|
{ CNAT_TEMP_SENSOR_CONFIG_FAILED,
|
|
1,
|
|
180,
|
|
{"Glik"}
|
|
},
|
|
{ HA_APP_NOT_RESPONDING,
|
|
2,
|
|
180,
|
|
{"CPU",
|
|
"Core"}
|
|
},
|
|
{ HA_DATA_PATH_TEST_FAILED,
|
|
0,
|
|
30,
|
|
{""}
|
|
},
|
|
{ CNAT_WRONG_PORT_ALLOC_TYPE,
|
|
3,
|
|
60,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_NEW_PORT_ALLOC_ERROR,
|
|
3,
|
|
60,
|
|
{"i-vrf",
|
|
"ipv4 addr",
|
|
"port"}
|
|
},
|
|
{ CNAT_INVALID_INDEX_TO_FREE_PORT,
|
|
0,
|
|
60,
|
|
{""}
|
|
},
|
|
{ CNAT_DELETE_DB_ENTRY_NO_PORTMAP,
|
|
0,
|
|
60,
|
|
{""}
|
|
},
|
|
{ CNAT_MAIN_DB_LIMIT_ERROR,
|
|
0,
|
|
180,
|
|
{""}
|
|
},
|
|
{ CNAT_USER_DB_LIMIT_ERROR,
|
|
0,
|
|
180,
|
|
{""}
|
|
},
|
|
{ CNAT_FRAG_DB_ERROR,
|
|
1,
|
|
180,
|
|
{"Type"}
|
|
},
|
|
|
|
{ DROP_PKT_DUMP,
|
|
0,
|
|
20,
|
|
{""}
|
|
}
|
|
};
|
|
|
|
#define LOG_TABLE_MAX_ENTRIES \
|
|
(sizeof(spp_cnat_logger_table)/sizeof(spp_cnat_logger_table[0]))
|
|
|
|
u32 error_code_timestamps[LOG_TABLE_MAX_ENTRIES];
|
|
spp_timer_t sensor_timer;
|
|
spp_trace_log_global_info_t spp_trace_log_global_info;
|
|
spp_global_counters_t spp_global_counters;
|
|
|
|
/*
|
|
* Logging information structures
|
|
*/
|
|
spp_trace_log_info_t spp_default_trace_log_info;
|
|
spp_trace_log_info_t *spp_trace_log_info_pool;
|
|
|
|
#ifdef TOBE_PORTED
|
|
/*
|
|
* The following 2 functions are temporary hacks until
|
|
* we have RTC support from the PD nodes
|
|
*/
|
|
inline
|
|
u32 spp_trace_log_get_sys_up_time_in_ms (void)
|
|
{
|
|
spp_node_main_vector_t *nmv;
|
|
u32 sys_up_time;
|
|
|
|
nmv = spp_get_node_main_vectorized_inline();
|
|
|
|
sys_up_time = (u32) (nmv->ticks / nmv->ticks_per_ms);
|
|
|
|
return (sys_up_time);
|
|
}
|
|
|
|
u32 spp_trace_log_get_unix_time_in_seconds (void)
|
|
{
|
|
spp_node_main_vector_t *nmv;
|
|
u32 unix_time;
|
|
|
|
nmv = spp_get_node_main_vectorized_inline();
|
|
|
|
unix_time = (u32) (nmv->ticks / nmv->ticks_per_second);
|
|
|
|
return (unix_time);
|
|
}
|
|
|
|
/*
|
|
* edt: * * spp_trace_log_send_queued_pkt
|
|
*
|
|
* Tries to send a logging pkt that has been queued earlier
|
|
* because it could not be sent due to downstream constipation
|
|
*
|
|
* Argument: spp_trace_log_info_t *trace_logging_info
|
|
* structure that contains the packet context
|
|
*/
|
|
inline
|
|
void spp_trace_log_send_queued_pkt (spp_trace_log_info_t *trace_logging_info)
|
|
{
|
|
spp_node_t *output_node;
|
|
|
|
output_node = spp_get_nodes() +
|
|
spp_trace_log_global_info.spp_trace_log_disp_node_index;
|
|
|
|
if (PREDICT_TRUE(output_node->sf.nused < SPP_MAXDISPATCH)) {
|
|
/*
|
|
* Move the logging context to output node
|
|
*/
|
|
spp_dispatch_make_node_runnable(output_node);
|
|
output_node->sf.ctxs[output_node->sf.nused++] =
|
|
trace_logging_info->queued_logging_context;
|
|
|
|
/*
|
|
* Context has been queued, it will be freed after the pkt
|
|
* is sent. Clear this from the logging_context_info structure
|
|
*/
|
|
trace_logging_info->queued_logging_context = NULL;
|
|
|
|
} else {
|
|
/*
|
|
* Can't do much, just return, may be we can send it later
|
|
*/
|
|
spp_global_counters.spp_trace_log_downstream_constipation_count++;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* edt: * * spp_trace_log_send_pkt
|
|
*
|
|
* Tries to send a logging pkt. If the packet cannot be sent
|
|
* because of rewrite_output node cannot process it, queue
|
|
* it temporarily and try to send it later.
|
|
*
|
|
* Argument: spp_trace_log_info_t *trace_logging_info
|
|
* structure that contains the packet context
|
|
*/
|
|
inline
|
|
void spp_trace_log_send_pkt (spp_trace_log_info_t *trace_logging_info)
|
|
{
|
|
spp_node_t *output_node;
|
|
|
|
|
|
output_node = spp_get_nodes() +
|
|
spp_trace_log_global_info.spp_trace_log_disp_node_index;
|
|
|
|
if (PREDICT_TRUE(output_node->sf.nused < SPP_MAXDISPATCH)) {
|
|
/*
|
|
* Move the logging context to output node
|
|
*/
|
|
spp_dispatch_make_node_runnable(output_node);
|
|
output_node->sf.ctxs[output_node->sf.nused++] =
|
|
trace_logging_info->current_logging_context;
|
|
|
|
} else {
|
|
/*
|
|
* Queue the context into the logging_info structure,
|
|
* We will try to send it later. Currently, we will
|
|
* restrict to only one context queued.
|
|
*/
|
|
spp_global_counters.spp_trace_log_downstream_constipation_count++;
|
|
|
|
/*
|
|
* Attach the current logging context which is full to the
|
|
* queued context list in trace_logging_info structure
|
|
*/
|
|
trace_logging_info->queued_logging_context =
|
|
trace_logging_info->current_logging_context;
|
|
|
|
/*
|
|
* Whether the context is queued or not, set the current context index
|
|
* to EMPTY, as the earlier context can no more be used to send
|
|
* more logging records.
|
|
*/
|
|
}
|
|
|
|
trace_logging_info->current_logging_context = NULL;
|
|
}
|
|
|
|
/*
|
|
* edt: * * spp_trace_log_send_pkt_always_success
|
|
*
|
|
* Tries to send a logging pkt. This cannot fail due to downstream
|
|
* constipation because we have already checked if the rewrite_output
|
|
* node can accept it.
|
|
*
|
|
* Argument: spp_trace_log_info_t *trace_logging_info
|
|
* structure that contains the packet context
|
|
*
|
|
* Argument: spp_node_t *output_node
|
|
* spp_node_t structure for rewrite_output node
|
|
*/
|
|
inline
|
|
void spp_trace_log_send_pkt_always_success (
|
|
spp_trace_log_info_t *trace_logging_info,
|
|
spp_node_t *output_node)
|
|
{
|
|
/*
|
|
* At this point we either have a current or queued logging context
|
|
*/
|
|
if (PREDICT_TRUE(trace_logging_info->current_logging_context != NULL)) {
|
|
|
|
output_node->sf.ctxs[output_node->sf.nused++] =
|
|
trace_logging_info->current_logging_context;
|
|
|
|
trace_logging_info->current_logging_context = NULL;
|
|
} else {
|
|
/*
|
|
* For queued logging context
|
|
*/
|
|
output_node->sf.ctxs[output_node->sf.nused++] =
|
|
trace_logging_info->queued_logging_context;
|
|
|
|
trace_logging_info->queued_logging_context = NULL;
|
|
}
|
|
|
|
/*
|
|
* Move the logging context to output node
|
|
*/
|
|
spp_dispatch_make_node_runnable(output_node);
|
|
|
|
}
|
|
|
|
/*
|
|
* edt: * * spp_create_trace_log_context
|
|
*
|
|
* Tries to create a logging context with packet buffer
|
|
* to send a new logging packet
|
|
*
|
|
* Argument: spp_trace_log_info_t *trace_logging_info
|
|
* structure that contains the nfv9 logging info and will store
|
|
* the packet context as well.
|
|
*/
|
|
inline
|
|
void spp_create_trace_log_context (
|
|
spp_trace_log_info_t *trace_logging_info)
|
|
{
|
|
spp_ctx_t *ctx;
|
|
|
|
/*
|
|
* If queued_logging_context_index is non-EMPTY, we already have a logging
|
|
* packet queued to be sent. First try sending this before allocating
|
|
* a new context. We can have only one active packet context per
|
|
* trace_logging_info structure
|
|
*/
|
|
if (PREDICT_FALSE(trace_logging_info->queued_logging_context != NULL)) {
|
|
spp_trace_log_send_queued_pkt(trace_logging_info);
|
|
/*
|
|
* If we cannot still send the queued pkt, just return
|
|
* Downstream Constipation count would have increased anyway
|
|
*/
|
|
if (trace_logging_info->queued_logging_context != NULL) {
|
|
spp_global_counters.spp_trace_log_context_creation_deferred_count++;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* No context can be allocated, return silently
|
|
* calling routine will handle updating the error counters
|
|
*/
|
|
if (spp_ctx_alloc(&ctx, 1) < 1) {
|
|
spp_global_counters.spp_trace_log_context_creation_fail_count++;
|
|
return;
|
|
}
|
|
|
|
trace_logging_info->current_logging_context = ctx;
|
|
trace_logging_info->pkt_length = 0;
|
|
|
|
trace_logging_info->current_logging_context_timestamp =
|
|
spp_trace_log_get_sys_up_time_in_ms();
|
|
|
|
ctx->flags = SPP_CTX_END_OF_PACKET;
|
|
ctx->ru.tx.from_node = NODE_TRACE_BACKUP;
|
|
ctx->ru.tx.dst_ip_port_idx = EXT_TRACE_BACKUP_INDEX;
|
|
ctx->next_ctx_this_packet = (spp_ctx_t*) SPP_CTX_NO_NEXT_CTX;
|
|
ctx->current_header = &ctx->packet_data[SPP_TRACE_LOG_HDR_OFFSET];
|
|
ctx->current_length = 0;
|
|
|
|
trace_logging_info->log_record = 0;
|
|
trace_logging_info->total_record_count = 0;
|
|
trace_logging_info->next_data_ptr =
|
|
(u8 *) &ctx->packet_data[SPP_TRACE_LOG_HDR_OFFSET];
|
|
|
|
}
|
|
|
|
/*
|
|
* edt: * * spp_trace_log_add_record_create
|
|
*
|
|
* Tries to create an add record to the NFV9 packet
|
|
*
|
|
* Argument: spp_trace_log_info_t *trace_logging_info
|
|
* structure that contains the nfv9 logging info and will store
|
|
* the packet context as well.
|
|
*/
|
|
inline
|
|
void spp_trace_log_add_record_create (spp_trace_log_info_t *trace_logging_info)
|
|
{
|
|
|
|
trace_logging_info->log_header =
|
|
(spp_trace_log_hdr_t *) (trace_logging_info->next_data_ptr);
|
|
|
|
/*
|
|
* Initialize the number of traces recorded
|
|
*/
|
|
trace_logging_info->log_header->num_traces =
|
|
spp_host_to_net_byte_order_32(0);
|
|
|
|
|
|
trace_logging_info->log_record =
|
|
(spp_trace_log_t *) (trace_logging_info->log_header + 1);
|
|
|
|
/*
|
|
* Update the length of the total pkt
|
|
*/
|
|
trace_logging_info->pkt_length +=
|
|
SPP_LOG_TRACE_HEADER_LENGTH;
|
|
|
|
/*
|
|
* Set the data pointer beyond the trace header field
|
|
*/
|
|
trace_logging_info->next_data_ptr =
|
|
(u8 *) (trace_logging_info->log_header + 1);
|
|
|
|
}
|
|
|
|
/*
|
|
* edt: * * spp_trace_logger
|
|
*
|
|
* Tries to log spp/cnat event/errors
|
|
*
|
|
* Argument: u8 *error_code
|
|
* Error code passed
|
|
*
|
|
* Argument: optional arguments
|
|
*/
|
|
void spp_trace_logger (u16 error_code, u16 num_args, u32 *arg)
|
|
{
|
|
spp_trace_log_info_t *trace_logging_info = 0;
|
|
u8 i;
|
|
|
|
trace_logging_info =
|
|
spp_trace_log_info_pool +
|
|
spp_trace_log_global_info.spp_log_pool_index[SPP_LOG_LTRACE];
|
|
|
|
if (PREDICT_FALSE(trace_logging_info->current_logging_context == NULL)) {
|
|
spp_create_trace_log_context(trace_logging_info);
|
|
|
|
/*
|
|
* If still empty, return after increasing the count
|
|
*/
|
|
if (PREDICT_FALSE(trace_logging_info->current_logging_context == NULL)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (PREDICT_FALSE(trace_logging_info->log_record == NULL)) {
|
|
spp_trace_log_add_record_create(trace_logging_info);
|
|
}
|
|
|
|
/*
|
|
* We should definitely have add_record now, no need to sanitize
|
|
*/
|
|
trace_logging_info->log_record->error_code =
|
|
spp_host_to_net_byte_order_16(error_code);
|
|
trace_logging_info->log_record->num_args =
|
|
spp_host_to_net_byte_order_16(num_args);
|
|
|
|
for (i = 0; i < num_args; i++) {
|
|
trace_logging_info->log_record->arg[i] =
|
|
spp_host_to_net_byte_order_32(*(arg + i));
|
|
}
|
|
|
|
trace_logging_info->pkt_length += SPP_TRACE_LOG_RECORD_LENGTH + WORD_SIZE*num_args;
|
|
trace_logging_info->current_logging_context->current_length =
|
|
trace_logging_info->pkt_length;
|
|
trace_logging_info->total_record_count += 1;
|
|
|
|
trace_logging_info->next_data_ptr =
|
|
(u8 *) (trace_logging_info->next_data_ptr + WORD_SIZE + WORD_SIZE*num_args);
|
|
|
|
trace_logging_info->log_record =
|
|
(spp_trace_log_t *) (trace_logging_info->next_data_ptr);
|
|
|
|
/*
|
|
* Initialize the number of traces recorded
|
|
*/
|
|
trace_logging_info->log_header->num_traces =
|
|
spp_host_to_net_byte_order_32(trace_logging_info->total_record_count);
|
|
|
|
|
|
|
|
/*
|
|
* If we have exceeded the packet length, let us send the
|
|
* packet now. There is buffer of additional bytes beyond
|
|
* max_pkt_length to ensure that the last add/delete record
|
|
* can be stored safely.
|
|
*/
|
|
if (trace_logging_info->pkt_length >
|
|
trace_logging_info->max_length_minus_max_record_size) {
|
|
spp_trace_log_send_pkt(trace_logging_info);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* edt: * * spp_trace_log_timer_handler
|
|
*
|
|
* Timer handler for sending any pending NFV9 record
|
|
*
|
|
* Argument: spp_timer_t * timer_p
|
|
* Timer handler structure
|
|
*/
|
|
inline
|
|
void spp_trace_log_timer_handler (spp_timer_t * timer_p)
|
|
{
|
|
spp_node_t *output_node;
|
|
spp_trace_log_info_t *trace_logging_info = 0;
|
|
u32 current_timestamp = spp_trace_log_get_sys_up_time_in_ms();
|
|
i16 sf_nused;
|
|
|
|
output_node = spp_get_nodes() +
|
|
spp_trace_log_global_info.spp_trace_log_disp_node_index;
|
|
|
|
sf_nused = output_node->sf.nused;
|
|
|
|
pool_foreach (trace_logging_info, spp_trace_log_info_pool, ({
|
|
/*
|
|
* Check if no more logging contexts can be queued
|
|
*/
|
|
if (PREDICT_FALSE(sf_nused >= SPP_MAXDISPATCH)) {
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* If there is a current logging context and timestamp
|
|
* indicates it is pending for long, send it out
|
|
* Also if there is a queued context send it out as well
|
|
*/
|
|
if (trace_logging_info->queued_logging_context ||
|
|
(trace_logging_info->current_logging_context &&
|
|
(current_timestamp -
|
|
trace_logging_info->current_logging_context_timestamp)
|
|
> 1000)) {
|
|
spp_trace_log_send_pkt_always_success(trace_logging_info,
|
|
output_node);
|
|
sf_nused++;
|
|
}
|
|
}));
|
|
|
|
timer_p->expires =
|
|
spp_timer_in_n_ms_inline(1000); /* every 1 sec */
|
|
spp_timer_start(timer_p);
|
|
|
|
}
|
|
inline
|
|
void spp_sensor_timer_handler (spp_timer_t * timer_p)
|
|
{
|
|
#ifdef TARGET_RODDICK
|
|
if (!temperature_read_blocked) {
|
|
Init_temperature_sensors();
|
|
read_octeon_sensors(TEMPERATURE_SENSOR_QUIET_MODE);
|
|
}
|
|
|
|
timer_p->expires =
|
|
spp_timer_in_n_ms_inline(60000); /* every 1 sec */
|
|
spp_timer_start(timer_p);
|
|
|
|
#endif
|
|
}
|
|
void init_trace_log_buf_pool (void)
|
|
{
|
|
spp_trace_log_info_t *my_spp_log_info;
|
|
u8 found;
|
|
spp_log_type_t log_type;
|
|
|
|
/*
|
|
* Init SPP logging info as needed, this will be done only once
|
|
*/
|
|
spp_trace_log_init();
|
|
|
|
found = 0;
|
|
|
|
for (log_type = SPP_LOG_LTRACE; log_type < SPP_LOG_MAX; log_type++ ) {
|
|
/* Do we already have a map for this log type? */
|
|
pool_foreach (my_spp_log_info, spp_trace_log_info_pool, ({
|
|
if (my_spp_log_info->log_type == log_type) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}));
|
|
|
|
/*
|
|
* Entry not present
|
|
*/
|
|
if (!found) {
|
|
pool_get(spp_trace_log_info_pool, my_spp_log_info);
|
|
memset(my_spp_log_info, 0, sizeof(*my_spp_log_info));
|
|
|
|
/*
|
|
* Make the current and head logging context indeices as EMPTY.
|
|
* When first logging happens, these get set correctly
|
|
*/
|
|
my_spp_log_info->current_logging_context = NULL;
|
|
my_spp_log_info->queued_logging_context = NULL;
|
|
|
|
my_spp_log_info->log_type = log_type;
|
|
my_spp_log_info->max_length_minus_max_record_size =
|
|
SPP_TRACE_LOG_MAX_PKT_LENGTH;
|
|
|
|
spp_trace_log_global_info.spp_log_pool_index[log_type] =
|
|
my_spp_log_info - spp_trace_log_info_pool;
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* one time function
|
|
* has to be called at the init time
|
|
*/
|
|
void spp_trace_log_init (void)
|
|
{
|
|
if (!spp_trace_log_global_info.spp_trace_log_init_done) {
|
|
|
|
#ifdef TARGET_RODDICK
|
|
spp_trace_log_global_info.spp_trace_log_disp_node_index =
|
|
spp_lookup_node_index("roddick_infra_l3_tx");
|
|
#elif defined(TARGET_BOOSTER)
|
|
spp_trace_log_global_info.spp_trace_log_disp_node_index =
|
|
spp_lookup_node_index("booster_infra_l3_tx");
|
|
#endif
|
|
ASSERT(spp_trace_log_global_info.spp_trace_log_disp_node_index != (u16)~0);
|
|
|
|
spp_trace_log_global_info.log_timer.cb_index =
|
|
spp_timer_register_callback(spp_trace_log_timer_handler);
|
|
spp_trace_log_global_info.log_timer.expires =
|
|
spp_timer_in_n_ms_inline(1000); /* every 1 sec */
|
|
spp_timer_start(&spp_trace_log_global_info.log_timer);
|
|
|
|
if (!my_core_id) {
|
|
sensor_timer.cb_index =
|
|
spp_timer_register_callback(spp_sensor_timer_handler);
|
|
sensor_timer.expires =
|
|
spp_timer_in_n_ms_inline(60000); /* every 1 sec */
|
|
spp_timer_start(&sensor_timer);
|
|
}
|
|
|
|
spp_trace_log_global_info.spp_trace_log_init_done = 1;
|
|
|
|
/*
|
|
* Set MSC ip_addr, port values
|
|
*/
|
|
#ifdef TARGET_RODDICK
|
|
dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].ipv4_address =
|
|
vpp_boot_params.msc_ip_address;
|
|
switch(vpp_boot_params.octeon_number) {
|
|
case 0:
|
|
dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
|
|
break;
|
|
case 1:
|
|
dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
|
|
break;
|
|
case 2:
|
|
dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
|
|
break;
|
|
case 3:
|
|
dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
|
|
break;
|
|
}
|
|
#else
|
|
dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].ipv4_address = 0x01020304;
|
|
dst_ipv4_port_table[EXT_TRACE_BACKUP_INDEX].port = 0x15BF;
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
void spp_printf (u16 error_code, u16 num_args, u32 *arg)
|
|
{
|
|
u32 current_timestamp;
|
|
spp_node_main_vector_t *nmv;
|
|
|
|
if (PREDICT_FALSE(error_code >= LOG_TABLE_MAX_ENTRIES))
|
|
{
|
|
/* printf("Error code invalid %d, %d, %d, %d\n",
|
|
error_code, LOG_TABLE_MAX_ENTRIES,
|
|
sizeof(spp_cnat_logger_table), sizeof(spp_cnat_logger_table[0]));
|
|
*/
|
|
return; /* Should not happen */
|
|
}
|
|
|
|
nmv = spp_get_node_main_vectorized_inline();
|
|
current_timestamp = nmv->ticks / nmv->ticks_per_second;
|
|
|
|
/* Check if any further hashing is required */
|
|
|
|
if (PREDICT_FALSE(error_code == DUMP_PKT_IDX)) {
|
|
#ifdef TARGET_RODDICK || defined(TARGET_BOOSTER)
|
|
spp_trace_logger(error_code, num_args, arg);
|
|
#else
|
|
u8 j ;
|
|
|
|
printf("PKT DUMP :: ");
|
|
for (j = 0 ; j < num_args; j++) {
|
|
printf("0x%x ", arg[j]);
|
|
if (j == (num_args - 1)) {
|
|
printf("\n");
|
|
}
|
|
}
|
|
#endif
|
|
} else if (PREDICT_TRUE((current_timestamp - error_code_timestamps[error_code]) >=
|
|
spp_cnat_logger_table[error_code].rate_limit_time)) {
|
|
/* update timestamp */
|
|
error_code_timestamps[error_code] = current_timestamp;
|
|
|
|
#ifdef TARGET_RODDICK || defined(TARGET_BOOSTER)
|
|
spp_trace_logger(error_code, num_args, arg);
|
|
#else
|
|
u8 j ;
|
|
|
|
for (j = 0 ; j < num_args; j++) {
|
|
printf("%s: %d ", spp_cnat_logger_table[error_code].param_name[j], arg[j]);
|
|
if (j == (num_args - 1)) {
|
|
printf("\n");
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#else /* TOBE_PORTEED */
|
|
void spp_trace_logger(u16 error_code, u16 num_args, u32 *arg)
|
|
{
|
|
/* To be filled */
|
|
}
|
|
|
|
void spp_trace_log_init(void)
|
|
{
|
|
/* To be filled */
|
|
}
|
|
|
|
void init_trace_log_buf_pool(void)
|
|
{
|
|
/* To be filled */
|
|
}
|
|
|
|
void spp_printf(u16 error_code, u16 num_args, u32 *arg)
|
|
{
|
|
/* To be filled */
|
|
}
|
|
|
|
inline u32 spp_trace_log_get_unix_time_in_seconds (void)
|
|
{
|
|
vlib_main_t *vlib_main;
|
|
|
|
vlib_main = vlib_get_main();
|
|
return(vlib_time_now((vlib_main_t *) vlib_main));
|
|
}
|
|
|
|
#endif /* TOBE_PORTED */
|
|
|