diff --git a/common/include/control_packet.h b/common/include/control_packet.h index 8db6eb1..f3e9a4b 100644 --- a/common/include/control_packet.h +++ b/common/include/control_packet.h @@ -16,6 +16,20 @@ enum session_state SESSION_STATE_RESETALL = 4, }; +enum control_packet_state +{ + CTRL_PKT_SUCCESS = 0, + CTRL_PKT_INVALID_FORMAT, + CTRL_PKT_INVALID_TSYNC, + CTRL_PKT_INVALID_SESSION_ID, + CTRL_PKT_INVALID_STATE, + CTRL_PKT_INVALID_METHOD, + CTRL_PKT_INVALID_POLICY_UPDATE, + CTRL_PKT_INVALID_PARAMS, + CTRL_PKT_INVALID_APP, + CTRL_PKT_INVALID_RULE_IDS, +}; + struct control_packet { char tsync[4]; @@ -27,10 +41,9 @@ struct control_packet }; const char *session_state_to_string(enum session_state state); +const char *control_packte_state_to_string(enum control_packet_state state); -// return 0 : success -// return -1 : error -int control_packet_parse(struct control_packet *handler, const char *data, size_t length); +enum control_packet_state control_packet_parse(struct control_packet *handler, const char *data, size_t length); void control_packet_dump(struct control_packet *handler); #ifdef __cpluscplus diff --git a/common/src/control_packet.cpp b/common/src/control_packet.cpp index eb1109d..27d3539 100644 --- a/common/src/control_packet.cpp +++ b/common/src/control_packet.cpp @@ -8,6 +8,35 @@ #include "utils.h" #include "control_packet.h" +const char *control_packte_state_to_string(enum control_packet_state state) +{ + switch (state) + { + case CTRL_PKT_SUCCESS: + return "success"; + case CTRL_PKT_INVALID_FORMAT: + return "failure (invalid format)"; + case CTRL_PKT_INVALID_TSYNC: + return "failure (invalid tsync)"; + case CTRL_PKT_INVALID_SESSION_ID: + return "failure (invalid session id)"; + case CTRL_PKT_INVALID_STATE: + return "failure (invalid state)"; + case CTRL_PKT_INVALID_METHOD: + return "failure (invalid method)"; + case CTRL_PKT_INVALID_POLICY_UPDATE: + return "failure (invalid policy update)"; + case CTRL_PKT_INVALID_PARAMS: + return "failure (invalid params)"; + case CTRL_PKT_INVALID_APP: + return "failure (invalid app)"; + case CTRL_PKT_INVALID_RULE_IDS: + return "failure (invalid rule ids)"; + default: + return "failure (unknown)"; + } +} + const char *session_state_to_string(enum session_state state) { switch (state) @@ -25,9 +54,7 @@ const char *session_state_to_string(enum session_state state) } } -// return 0 : success -// return -1 : error -int control_packet_parse(struct control_packet *handler, const char *data, size_t length) +enum control_packet_state control_packet_parse(struct control_packet *handler, const char *data, size_t length) { memset(handler, 0, sizeof(struct control_packet)); @@ -37,6 +64,7 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ mpack_node_t item; mpack_error_t ret; char buffer[16]; + enum control_packet_state state = CTRL_PKT_SUCCESS; mpack_tree_init_data(&tree, data, length); mpack_tree_parse(&tree); @@ -44,6 +72,7 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(root)) { LOG_ERROR("%s: unexpected control packet: (invalid mpack format)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_FORMAT; goto error_out; } @@ -52,12 +81,14 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(temp)) { LOG_ERROR("%s: unexpected control packet: (tsync no found)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_TSYNC; goto error_out; } mpack_node_copy_cstr(temp, handler->tsync, sizeof(handler->tsync)); if (strcasecmp(handler->tsync, "2.0") != 0) { LOG_ERROR("%s: unexpected control packet: (invalid tsync value) %s", LOG_TAG_CTRLPKT, handler->tsync); + state = CTRL_PKT_INVALID_TSYNC; goto error_out; } @@ -66,6 +97,7 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(temp)) { LOG_ERROR("%s: unexpected control packet: (session_id no found)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_SESSION_ID; goto error_out; } handler->session_id = mpack_node_u64(temp); @@ -83,6 +115,7 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(temp)) { LOG_ERROR("%s: unexpected control packet: (state no found)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_STATE; goto error_out; } mpack_node_copy_cstr(temp, buffer, sizeof(buffer)); @@ -105,6 +138,7 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ else { LOG_ERROR("%s: unexpected control packet: (invalid state value) %s", LOG_TAG_CTRLPKT, buffer); + state = CTRL_PKT_INVALID_STATE; goto error_out; } if (handler->state != SESSION_STATE_ACTIVE) @@ -117,12 +151,14 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(temp)) { LOG_ERROR("%s: unexpected control packet: (method no found)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_METHOD; goto error_out; } mpack_node_copy_cstr(temp, handler->method, sizeof(handler->method)); if (strcasecmp(handler->method, "policy_update") != 0) { LOG_ERROR("%s: unexpected control packet: (invalid method value) %s", LOG_TAG_CTRLPKT, handler->method); + state = CTRL_PKT_INVALID_POLICY_UPDATE; goto error_out; } @@ -131,6 +167,7 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(temp)) { LOG_ERROR("%s: unexpected control packet: (params no found)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_PARAMS; goto error_out; } // params->sce @@ -138,6 +175,7 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(temp)) { LOG_ERROR("%s: unexpected control packet: (sce no found)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_APP; goto error_out; } // params->sce->rule_ids @@ -145,12 +183,14 @@ int control_packet_parse(struct control_packet *handler, const char *data, size_ if (mpack_node_is_nil(temp)) { LOG_ERROR("%s: unexpected control packet: (rule_ids no found)", LOG_TAG_CTRLPKT); + state = CTRL_PKT_INVALID_RULE_IDS; goto error_out; } handler->rule_id_num = MIN(mpack_node_array_length(temp), (int)(sizeof(handler->rule_ids) / sizeof(handler->rule_ids[0]))); if (handler->rule_id_num <= 0) { LOG_ERROR("%s: unexpected control packet: (invalid rule id num) %ld", LOG_TAG_CTRLPKT, mpack_node_array_length(temp)); + state = CTRL_PKT_INVALID_RULE_IDS; goto error_out; } for (int i = 0; i < handler->rule_id_num; i++) @@ -164,14 +204,15 @@ success_out: if (ret != mpack_ok) { LOG_ERROR("%s: unexpected control packet: (mpack return error) %d", LOG_TAG_CTRLPKT, ret); - return -1; + state = CTRL_PKT_INVALID_FORMAT; + return state; } - return 0; + return state; error_out: mpack_tree_destroy(&tree); - return -1; + return state; } void control_packet_dump(struct control_packet *handler) diff --git a/common/test/gtest_control_packet.cpp b/common/test/gtest_control_packet.cpp index 9ea09d9..b010b63 100644 --- a/common/test/gtest_control_packet.cpp +++ b/common/test/gtest_control_packet.cpp @@ -290,7 +290,7 @@ TEST(CONTROL_PACKET, PACKAGE2) TEST(CONTROL_PACKET, PARSE0) { struct control_packet handler; - EXPECT_TRUE(control_packet_parse(&handler, (const char *)control_packet_active0, sizeof(control_packet_active0)) == 0); + EXPECT_TRUE(control_packet_parse(&handler, (const char *)control_packet_active0, sizeof(control_packet_active0)) == CTRL_PKT_SUCCESS); control_packet_dump(&handler); EXPECT_STREQ(handler.tsync, "2.0"); @@ -305,7 +305,7 @@ TEST(CONTROL_PACKET, PARSE0) TEST(CONTROL_PACKET, PARSE1) { struct control_packet handler; - EXPECT_TRUE(control_packet_parse(&handler, (const char *)control_packet_active1, sizeof(control_packet_active1)) == 0); + EXPECT_TRUE(control_packet_parse(&handler, (const char *)control_packet_active1, sizeof(control_packet_active1)) == CTRL_PKT_SUCCESS); control_packet_dump(&handler); EXPECT_STREQ(handler.tsync, "2.0"); @@ -319,7 +319,7 @@ TEST(CONTROL_PACKET, PARSE1) TEST(CONTROL_PACKET, PARSE2) { struct control_packet handler; - EXPECT_TRUE(control_packet_parse(&handler, (const char *)control_packet_opening, sizeof(control_packet_opening)) == 0); + EXPECT_TRUE(control_packet_parse(&handler, (const char *)control_packet_opening, sizeof(control_packet_opening)) == CTRL_PKT_SUCCESS); control_packet_dump(&handler); EXPECT_STREQ(handler.tsync, "2.0"); diff --git a/platform/include/packet_trace.h b/platform/include/packet_trace.h new file mode 100644 index 0000000..77e1bc4 --- /dev/null +++ b/platform/include/packet_trace.h @@ -0,0 +1,135 @@ +#ifndef _PACKET_TRACE_H +#define _PACKET_TRACE_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include "utils.h" +#include "policy.h" + +#include + +/* + * SCE packet trace info format + * + * PACKET_TRACE_ON_NEW : "(Packet I/O) new packet" + * PACKET_TRACE_ON_FREE : "(Packet I/O) free packet" + * PACKET_TRACE_ON_CTRL : "(Session Synchronization) ${MSG}" + * + * Service Function Path (SFP) https://datatracker.ietf.org/doc/html/rfc7665 + * + * PACKET_TRACE_ON_POLICY : "(Policy) rule_list: [${Rule_ID1}, ${Rule_ID2}, ...], SFP_list: [${SF_ID1}, ${SF_ID2}, ...]" + * PACKET_TRACE_ON_CHAIN : "(Forwarder) SF_id: ${SF_ID}, fwd_type: ${FWD_TYPE}, pkt_dir: ${PKT_DIR}, pkt_type: ${PKT_TYPE}, state: ${STATE} ${ACTION}" + * + * ${FWD_TYPE} + * steering + * mirroring + * + * ${PKT_DIR} + * I2E + * E2I + * + * ${PKT_TYPE} + * raw + * decrypted + * + * ${STATE} + * success + * failure + * + * ${ACTION} + * bypass + * block + * re-dispatch block + * re-dispatch bypass + * re-dispatch bypass(health SF limit) + * + * bypass(default) + * bypass(invalid policy) + */ + +static inline int rule_id_tostring(struct mutable_array *rule_ids, char *buffer, int size) +{ + int used = 0; + used += snprintf(buffer + used, size - used, "["); + for (int i = 0; i < rule_ids->num; i++) + { + used += snprintf(buffer + used, size - used, "%lu", rule_ids->elems[i]); + if (i < rule_ids->num - 1) + { + used += snprintf(buffer + used, size - used, ", "); + } + } + used += snprintf(buffer + used, size - used, "]"); + return used; +} + +static inline int sf_id_tostring(struct selected_chaining *chain, char *buffer, int size) +{ + int used = 0; + used += snprintf(buffer + used, size - used, "["); + for (int i = 0; i < chain->chaining_used; i++) + { + used += snprintf(buffer + used, size - used, "%d", chain->chaining[i].sf_profile_id); + if (i < chain->chaining_used - 1) + { + used += snprintf(buffer + used, size - used, ", "); + } + } + used += snprintf(buffer + used, size - used, "]"); + return used; +} + +#define PACKET_IO_TRACE(mr_ins, mr_buff, str) \ + { \ + if (marsio_dp_trace_record_can_emit(mr_buff)) \ + { \ + marsio_dp_trace_record_emit_str(mr_ins, mr_buff, "(Packet I/O)", str); \ + } \ + } + +#define PACKET_TRACE_ON_NEW(mr_ins, mr_buff) PACKET_IO_TRACE(mr_ins, mr_buff, "new packet") +#define PACKET_TRACE_ON_FREE(mr_ins, mr_buff) PACKET_IO_TRACE(mr_ins, mr_buff, "free packet") + +#define PACKET_TRACE_ON_CTRL(mr_ins, mr_buff, state) \ + { \ + if (marsio_dp_trace_record_can_emit(mr_buff)) \ + { \ + marsio_dp_trace_record_emit_fmt(mr_ins, mr_buff, "(Session Synchronization)", "%s", control_packte_state_to_string(state)); \ + } \ + } + +#define PACKET_TRACE_ON_POLICY(mr_ins, mr_buff, rule_ids, chain) \ + { \ + if (marsio_dp_trace_record_can_emit(mr_buff)) \ + { \ + char buffer1[1024] = {0}; \ + char buffer2[1024] = {0}; \ + rule_id_tostring(rule_ids, buffer1, sizeof(buffer1)); \ + sf_id_tostring(chain, buffer2, sizeof(buffer2)); \ + marsio_dp_trace_record_emit_fmt(mr_ins, mr_buff, "(Policy)", "rule_list: %s, SFP_list: %s", buffer1, buffer2); \ + } \ + } + +#define PACKET_TRACE_ON_CHAIN(mr_ins, mr_buff, sf, meta) \ + { \ + if (marsio_dp_trace_record_can_emit(mr_buff)) \ + { \ + marsio_dp_trace_record_emit_fmt(mr_ins, mr_buff, "(Forwarder)", \ + "SF_id: %d, fwd_type: %s, pkt_dir: %s, pkt_type: %s, state: %s %s", \ + (sf)->sf_profile_id, \ + forward_type_tostring((sf)->sff_forward_type), \ + ((meta)->direction ? "E2I" : "I2E"), \ + ((meta)->is_decrypted ? "decrypted" : "raw"), \ + ((sf)->sf_action == SESSION_ACTION_FORWARD ? "success" : "failure"), \ + ((sf)->sf_action == SESSION_ACTION_FORWARD ? "" : action_desc_tostring((sf)->sf_action_desc))); \ + } \ + } + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/platform/src/packet_io.cpp b/platform/src/packet_io.cpp index 18ca37a..c27f512 100644 --- a/platform/src/packet_io.cpp +++ b/platform/src/packet_io.cpp @@ -14,6 +14,7 @@ #include "utils.h" #include "vxlan.h" #include "packet_io.h" +#include "packet_trace.h" #include "sf_metrics.h" #include "control_packet.h" #include "global_metrics.h" @@ -528,6 +529,7 @@ static inline int send_packet_to_sf(struct session_ctx *session_ctx, marsio_buff meta->direction, meta->is_decrypted, sf->sf_index); nsend = marsio_buff_datalen(mbuff); marsio_buff_set_metadata(mbuff, MR_BUFF_REHASH_INDEX, &rehash_index, sizeof(rehash_index)); + PACKET_TRACE_ON_NEW(packet_io->instance, mbuff); marsio_send_burst(packet_io->dev_endpoint_l3.mr_path, thread_ctx->thread_index, &mbuff, 1); THROUGHPUT_METRICS_INC(&(thread_metrics->endpoint_vxlan_tx), 1, nsend); break; @@ -537,6 +539,7 @@ static inline int send_packet_to_sf(struct session_ctx *session_ctx, marsio_buff packet_io->config.vlan_encapsulate_replace_orig_vlan_header); nsend = marsio_buff_datalen(mbuff); marsio_buff_set_metadata(mbuff, MR_BUFF_REHASH_INDEX, &rehash_index, sizeof(rehash_index)); + PACKET_TRACE_ON_NEW(packet_io->instance, mbuff); marsio_send_burst(packet_io->dev_endpoint_l2.mr_path, thread_ctx->thread_index, &mbuff, 1); THROUGHPUT_METRICS_INC(&(thread_metrics->endpoint_vlan_tx), 1, nsend); break; @@ -570,6 +573,7 @@ static inline void action_err_block(marsio_buff_t *rx_buff, struct metadata *met int thread_index = thread_ctx->thread_index; THROUGHPUT_METRICS_INC(&(thread_metrics->error_block), 1, meta->raw_len); + PACKET_TRACE_ON_FREE(packet_io->instance, rx_buff); marsio_buff_free(packet_io->instance, &rx_buff, 1, 0, thread_index); } @@ -649,6 +653,7 @@ static inline void action_stee_block(marsio_buff_t *rx_buff, struct metadata *me int thread_index = thread_ctx->thread_index; THROUGHPUT_METRICS_INC(&(thread_metrics->stee_block), 1, meta->raw_len); + PACKET_TRACE_ON_FREE(packet_io->instance, rx_buff); marsio_buff_free(packet_io->instance, &rx_buff, 1, 0, thread_index); } @@ -679,6 +684,7 @@ static void action_sf_chaining(struct thread_ctx *thread_ctx, struct session_ctx sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, (meta->is_decrypted ? "decrypted" : "raw"), (meta->direction ? "E2I" : "I2E"), forward_type_tostring(sf->sff_forward_type), action_desc_tostring(sf->sf_action_desc)); + PACKET_TRACE_ON_CHAIN(thread_ctx->ref_io->instance, rx_buff, sf, meta); switch (sf->sf_action) { case SESSION_ACTION_BYPASS: @@ -873,6 +879,7 @@ static int send_ctrl_packet(struct session_ctx *session_ctx, struct thread_ctx * route_ctx_copy(&meta.route_ctx, &(session_ctx->ctrl_route_ctx)); mbuff_set_metadata(tx_buffs[0], &meta); int nsend = marsio_buff_datalen(tx_buffs[0]); + PACKET_TRACE_ON_NEW(packet_io->instance, tx_buffs[0]); marsio_send_burst(packet_io->dev_nf.mr_path, thread_index, tx_buffs, 1); free(data); @@ -1050,6 +1057,7 @@ static void handle_control_packet(marsio_buff_t *rx_buff, struct thread_ctx *thr struct thread_metrics *thread_metrics = &thread_ctx->thread_metrics; struct metadata meta; struct control_packet ctrl_pkt; + enum control_packet_state packet_state = CTRL_PKT_SUCCESS; memset(&meta, 0, sizeof(struct metadata)); meta.is_ctrl_pkt = 1; @@ -1061,7 +1069,8 @@ static void handle_control_packet(marsio_buff_t *rx_buff, struct thread_ctx *thr goto error_ctrl_pkt; } - if (control_packet_parse(&ctrl_pkt, meta.raw_data + meta.l7offset, meta.raw_len - meta.l7offset) == -1) + packet_state = control_packet_parse(&ctrl_pkt, meta.raw_data + meta.l7offset, meta.raw_len - meta.l7offset); + if (packet_state != CTRL_PKT_SUCCESS) { LOG_ERROR("%s: unexpected control packet, unable to parse data", LOG_TAG_PKTIO); goto error_ctrl_pkt; @@ -1070,6 +1079,7 @@ static void handle_control_packet(marsio_buff_t *rx_buff, struct thread_ctx *thr if (ctrl_pkt.session_id != meta.session_id) { LOG_ERROR("%s: unexpected control packet, metadata's session %lu != control packet's session %lu", LOG_TAG_PKTIO, meta.session_id, ctrl_pkt.session_id); + packet_state = CTRL_PKT_INVALID_SESSION_ID; goto error_ctrl_pkt; } @@ -1095,9 +1105,11 @@ static void handle_control_packet(marsio_buff_t *rx_buff, struct thread_ctx *thr default: goto error_ctrl_pkt; } + PACKET_TRACE_ON_CTRL(thread_ctx->ref_io->instance, rx_buff, packet_state); return; error_ctrl_pkt: + PACKET_TRACE_ON_CTRL(thread_ctx->ref_io->instance, rx_buff, packet_state); ATOMIC_INC(&(thread_metrics->ctrl_error)); return; } @@ -1160,6 +1172,7 @@ static void handle_data_packet(marsio_buff_t *rx_buff, struct thread_ctx *thread goto error_bypass; } + PACKET_TRACE_ON_POLICY(thread_ctx->ref_io->instance, rx_buff, &session_ctx->rule_ids, chaining); action_sf_chaining(thread_ctx, session_ctx, chaining, rx_buff, &meta, 0); return; @@ -1512,7 +1525,8 @@ int packet_io_polling_nf(struct packet_io *handle, struct thread_ctx *thread_ctx { for (int j = 0; j < nr_recv; j++) { - int raw_len = marsio_buff_datalen(rx_buffs[j]); + marsio_buff_t *rx_buff = rx_buffs[j]; + int raw_len = marsio_buff_datalen(rx_buff); THROUGHPUT_METRICS_INC(&(thread_metrics->nf_rx), 1, raw_len); THROUGHPUT_METRICS_INC(&(thread_metrics->nf_tx), 1, raw_len); @@ -1582,6 +1596,7 @@ int packet_io_polling_endpoint_l3(struct packet_io *handle, struct thread_ctx *t THROUGHPUT_METRICS_INC(&(thread_metrics->uplink_rx), 1, raw_len); THROUGHPUT_METRICS_INC(&(thread_metrics->uplink_tx_drop), 1, raw_len); + PACKET_TRACE_ON_FREE(handle->instance, rx_buff); marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_index); } else @@ -1615,6 +1630,7 @@ int packet_io_polling_endpoint_l2(struct packet_io *handle, struct thread_ctx *t THROUGHPUT_METRICS_INC(&(thread_metrics->endpoint_vlan_rx), 1, raw_len); THROUGHPUT_METRICS_INC(&(thread_metrics->endpoint_vlan_drop), 1, raw_len); + PACKET_TRACE_ON_FREE(handle->instance, rx_buff); marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_index); } diff --git a/platform/src/policy.cpp b/platform/src/policy.cpp index 018c15a..7becfc2 100644 --- a/platform/src/policy.cpp +++ b/platform/src/policy.cpp @@ -1298,24 +1298,20 @@ const char *action_desc_tostring(enum action_desc action_desc) { switch (action_desc) { - case ACTION_BYPASS_DUE_DEFAULT: - return "bypass(default)"; - case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT: - return "bypass(health_sf_limit)"; - case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION: - return "bypass(unavailable_action)"; - case ACTION_BYPASS_DUE_FAILURE_ACTION: - return "bypass(failure_action)"; - case ACTION_BYPASS_DUE_INVALID_POLICY: - return "bypass(invalid_policy)"; - case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION: - return "block(unavailable_action)"; - case ACTION_BLOCK_DUE_FAILURE_ACTION: - return "block(failure_action)"; - case ACTION_FORWAED_DUE_SELECTED_SF: - return "forward(selected_sf)"; + // success action + case ACTION_FORWAED_DUE_SELECTED_SF: return "forward"; + // failure action + case ACTION_BYPASS_DUE_FAILURE_ACTION: return "bypass"; + case ACTION_BLOCK_DUE_FAILURE_ACTION: return "block"; + case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION: return "re-dispatch block"; + case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION: return "re-dispatch bypass"; + case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT: return "re-dispatch bypass(health SF limit)"; + // default action + case ACTION_BYPASS_DUE_DEFAULT: return "bypass(default)"; + case ACTION_BYPASS_DUE_INVALID_POLICY: return "bypass(invalid policy)"; + // unreachable default: - return "unknown"; + return "action unknown"; } } diff --git a/test/gmock_marsio.cpp b/test/gmock_marsio.cpp index 31127bc..7d812a4 100644 --- a/test/gmock_marsio.cpp +++ b/test/gmock_marsio.cpp @@ -484,4 +484,19 @@ marsio_buff_t *marsio_mbuff_dup(marsio_buff_t *m) mbuf->raw_len = orig->raw_len; return mbuf; +} + +int marsio_dp_trace_record_can_emit(const marsio_buff_t *mbuf) +{ + return 0; +} + +int marsio_dp_trace_record_emit_str(struct mr_instance *instance, marsio_buff_t *mbuf, const char *module, const char *str) +{ + return 0; +} + +int marsio_dp_trace_record_emit_fmt(struct mr_instance *instance, marsio_buff_t *mbuf, const char *module, const char *format, ...) +{ + return 0; } \ No newline at end of file