diff options
| author | tongzongzhen <[email protected]> | 2024-10-18 14:33:40 +0800 |
|---|---|---|
| committer | tongzongzhen <[email protected]> | 2024-10-18 14:33:40 +0800 |
| commit | 2d714a5cec1232f9bd855fc2461141248785858c (patch) | |
| tree | 557cdeb429e36406cc2427e7e10b041fff43e03f | |
| parent | 78d4bc884c5c395f785b949633a2b1dcea79ff79 (diff) | |
increase bpf expr len to 256 charv4.8.21-20241018
| -rw-r--r-- | include/external/marsio.h | 4 | ||||
| -rw-r--r-- | infra/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | infra/test/TestDataPathTrace.c | 468 | ||||
| -rw-r--r-- | infra/test/TestDataPathTrace.cc | 387 |
4 files changed, 472 insertions, 391 deletions
diff --git a/include/external/marsio.h b/include/external/marsio.h index 12e4bd1..b789ec2 100644 --- a/include/external/marsio.h +++ b/include/external/marsio.h @@ -309,7 +309,7 @@ int marsio_dp_trace_measurement_emit_fmt(struct mr_instance * instance, marsio_b /////////////////////// only for data path trace telemetry //////////// #ifndef MR_BPF_EXPRESSION_MAX -#define MR_BPF_EXPRESSION_MAX 128 +#define MR_BPF_EXPRESSION_MAX 256 #endif #define DP_TRACE_TRAFFIC_LINK_ID_ARRAY_SIZE_MAX 8 @@ -352,12 +352,12 @@ struct dp_trace_job_desc bool enable; uint8_t measurement_type; int8_t rule_index; - char bpf_expr[MR_BPF_EXPRESSION_MAX]; unsigned int pkt_cnt_max; // The final number of captured packets unsigned int sampling; unsigned int snaplen; uint8_t traffic_link_id_cnt; uint16_t traffic_link_ids[DP_TRACE_TRAFFIC_LINK_ID_ARRAY_SIZE_MAX]; + char bpf_expr[MR_BPF_EXPRESSION_MAX]; }; int marsio_dp_trace_job_id_uesd_get(struct mr_instance * instance, job_bitmap_t * jobs_id); diff --git a/infra/CMakeLists.txt b/infra/CMakeLists.txt index e61bc49..9702955 100644 --- a/infra/CMakeLists.txt +++ b/infra/CMakeLists.txt @@ -42,8 +42,8 @@ add_executable(TestPortAdapterMapping test/TestPortAdapterMapping.cc) target_link_libraries(TestPortAdapterMapping infra z elf ibverbs gtest_main ${SYSTEMD_LIBRARIES} libdpdk) target_include_directories(TestPortAdapterMapping PRIVATE include) -add_executable(TestDataPathTrace test/TestDataPathTrace.cc) -target_link_libraries(TestDataPathTrace gtest_main infra z elf ibverbs libdpdk ${SYSTEMD_LIBRARIES}) +add_executable(TestDataPathTrace test/TestDataPathTrace.c) +target_link_libraries(TestDataPathTrace gtest_main infra z elf ibverbs libcmocka libdpdk ${SYSTEMD_LIBRARIES}) target_include_directories(TestDataPathTrace PRIVATE include) add_test(TestPacketParser TestPacketParser) diff --git a/infra/test/TestDataPathTrace.c b/infra/test/TestDataPathTrace.c new file mode 100644 index 0000000..6d0ff34 --- /dev/null +++ b/infra/test/TestDataPathTrace.c @@ -0,0 +1,468 @@ + +#include <setjmp.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <cmocka.h> + +#include <rte_common.h> +#include <rte_eal.h> +#include <rte_errno.h> +#include <rte_malloc.h> + +#include "dp_trace.h" +#include "ldbc.h" +#include "mrb_define.h" + +unsigned int g_logger_to_stdout = 1; +unsigned int g_logger_level = LOG_DEBUG; +struct dp_trace_process * trace; +struct rte_mempool * mempool; + +/* 73 Ether/IPv4/UDP/G-VxLan/Ether/VLAN/IPv4/TCP + + Outer Ether e8:4d:d0:ca:3a:1f -> 58:69:6c:6f:96:f3 + Outer IPv4 1.1.15.100 -> 10.0.4.120 + Outer UDP 60014 -> 4789 + + Outer Ether 64:f6:9d:5f:b9:76 -> a4:93:4c:c6:e5:5f + Inner IPv4 125.33.49.137 -> 39.66.162.89 + Inner TCP 28402→11235 +*/ + +/* Frame (114 bytes) */ +static const unsigned char pkt73[114] = { + 0xe8, 0x4d, 0xd0, 0xca, 0x3a, 0x1f, 0x58, 0x69, /* .M..:.Xi */ + 0x6c, 0x6f, 0x96, 0xf3, 0x08, 0x00, 0x45, 0x00, /* lo....E. */ + 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x11, /* .d...... */ + 0x9e, 0xac, 0x01, 0x01, 0x0f, 0x64, 0x0a, 0x00, /* .....d.. */ + 0x04, 0x78, 0xea, 0x6e, 0x12, 0xb5, 0x00, 0x50, /* .x.n...P */ + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x50, /* .......P */ + 0x01, 0x00, 0x64, 0xf6, 0x9d, 0x5f, 0xb9, 0x76, /* ..d.._.v */ + 0xa4, 0x93, 0x4c, 0xc6, 0xe5, 0x5f, 0x81, 0x00, /* ..L.._.. */ + 0x00, 0x01, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, /* ....E..( */ + 0x59, 0x6f, 0x40, 0x00, 0x7b, 0x06, 0x2e, 0x1b, /* Yo@.{... */ + 0x7d, 0x21, 0x31, 0x89, 0x27, 0x42, 0xa2, 0x59, /* }!1.'B.Y */ + 0x6e, 0xf2, 0x2b, 0xe3, 0xa5, 0x40, 0xd8, 0x7f, /* n.+..@.. */ + 0x9d, 0x5c, 0x74, 0xba, 0x50, 0x10, 0xfb, 0xb8, /* .\t.P... */ + 0x11, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .)...... */ + 0x00, 0x00 /* .. */ +}; + +int contains_substring(const char * str, const char * substr, size_t len); + +static int setup_testcase(void ** state) +{ + const char * argv[] = {"TestDataPathTrace", "-c", "0x1", "--no-huge", "-m", "512", "--no-pci"}; + if (rte_eal_init(RTE_DIM(argv), (char **)argv) < 0) + { + rte_exit(EXIT_FAILURE, "failed at rte_eal_init()"); + return 1; + } + return 0; +} + +static int teardown_testCase(void ** state) +{ + rte_eal_cleanup(); + return 0; +} + +static int setup(void ** state) +{ + // create trace + trace = dp_trace_process_create(DP_TRACE_PROCESS_MARSIO); + trace->inst->enable = true; + unsigned int sz_align_priv = RTE_ALIGN(sizeof(struct mrb_metadata), RTE_MBUF_PRIV_ALIGN); + mempool = rte_pktmbuf_pool_create("dp_trace_dump_pool", 16, 0, sz_align_priv, + DP_TRACE_RECORD_SIZE + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + return 0; +} + +void dp_trace_process_destroy(struct dp_trace_process * trace, enum dp_trace_process_type process_tpye) +{ + // This function is for unit testing only. This instance created by marsio or app should not be deleted + // manually. It accompanies the entire life cycle of the process. + if (process_tpye == DP_TRACE_PROCESS_MARSIO) + { + rte_mempool_free(trace->inst->pool); + rte_mempool_free(mempool); + for (unsigned int i = 0; i < trace->inst->nr_ring; i++) + { + rte_ring_free(trace->inst->ring[i]); + } + FREE(trace->inst); + FREE(trace); + } + else + { + FREE(trace); + } +} + +static int teardown(void ** state) +{ + dp_trace_process_destroy(trace, DP_TRACE_PROCESS_MARSIO); + return 0; +} + +struct rte_mbuf * mbuf_construct(const unsigned char * pkt, unsigned int len) +{ + if (trace == NULL) + return NULL; + + struct rte_mbuf * pkt_mbuf = rte_pktmbuf_alloc(mempool); + unsigned int sz_align_priv = RTE_ALIGN(sizeof(struct mrb_metadata), RTE_MBUF_PRIV_ALIGN); + + uint16_t data_off = sizeof(struct rte_mbuf) + sz_align_priv; + unsigned char * data_addr = (unsigned char *)pkt_mbuf->buf_addr + data_off; + memcpy(data_addr, pkt, len); + pkt_mbuf->data_off = data_off; + pkt_mbuf->data_len = len; + pkt_mbuf->pkt_len = len; + pkt_mbuf->nb_segs = 1; + pkt_mbuf->next = NULL; + + // parse mbuf + struct pkt_parser _pkt_handler; + struct pkt_parser_result _pkt_result; + pkt_parser_init(&_pkt_handler, &_pkt_result, LAYER_TYPE_ALL, MR_PKT_PARSER_LAYERS_MAX); + pkt_parser_exec(&_pkt_handler, pkt_mbuf); + + struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt_mbuf, 1); + struct pkt_parser_result * pkt_parser_result = &mrb_meta->pkt_parser_result; + memcpy(pkt_parser_result, &_pkt_result, sizeof(struct pkt_parser_result)); + mrb_meta->dp_trace_buffer = NULL; + + return pkt_mbuf; +} + +static void testcase_packet_construct(void ** state) +{ + struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); + + struct rte_mbuf * mbuf = (struct rte_mbuf *)rte_zmalloc(NULL, sizeof(struct rte_mbuf), 0); + mbuf->buf_len = sizeof(pkt73); + mbuf->buf_addr = (void *)(const char *)pkt73; + mbuf->data_off = 0; + mbuf->data_len = sizeof(pkt73); + mbuf->pkt_len = sizeof(pkt73); + mbuf->nb_segs = 1; + mbuf->next = NULL; + + struct pkt_parser _pkt_handler; + struct pkt_parser_result _pkt_parser; + pkt_parser_init(&_pkt_handler, &_pkt_parser, LAYER_TYPE_ALL, MR_PKT_PARSER_LAYERS_MAX); + pkt_parser_exec(&_pkt_handler, mbuf); + unsigned int inner_ether_offset = _pkt_parser.layers[4].offset; + + assert_true(mrb_meta->pkt_parser_result.layers[4].offset == inner_ether_offset); + + FREE(mbuf); + infra_rte_pktmbuf_free(pkt73_mbuf); +} + +static void testcase_instance_create(void ** state) +{ + assert_true(trace->inst != NULL); +} + +static void testcase_job_init(void ** state) +{ + int n; + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 0, + .bpf_expr = "ether host 64:f6:9d:5f:b9:76", + .pkt_cnt_max = 10, + .sampling = 1, + }; + n = dp_trace_job_add(trace, &desc); + assert_true(n >= 0); + assert_true(trace->inst->job_ctx[0].used == true); +} + +static void testcase_job_destroy(void ** state) +{ + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 0, + .bpf_expr = "ether host 64:f6:9d:5f:b9:76", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc); + + struct dp_trace_job_desc desc_2 = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 1, + .bpf_expr = "vlan && ip src 125.33.49.137", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc_2); + + dp_trace_jobs_destroy(trace, 1 | 1 << 1); + + assert_true(trace->inst->job_ctx[0].used == false); + assert_true(trace->inst->job_ctx[1].used == false); +} + +static void testcase_job_bpf_match(void ** state) +{ + struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); + unsigned int offset = mrb_meta->pkt_parser_result.layers[4].offset; + + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 0, + .bpf_expr = "ether host 64:f6:9d:5f:b9:76", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc); + + struct dp_trace_job_desc desc_2 = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 1, + .bpf_expr = "vlan && ip src 125.33.49.137", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc_2); + + dp_trace_filter_exec(trace, pkt73_mbuf, offset, 0); + u_int16_t ret = dp_trace_job_id_bitmap_get(trace, pkt73_mbuf); + assert_true(ret == 3); + + struct dp_trace_buffer * dp_trace_buffer = (struct dp_trace_buffer *)mrb_meta->dp_trace_buffer; + assert_true(dp_trace_buffer != NULL); + assert_true(dp_trace_buffer->jobs == 3); + + infra_rte_pktmbuf_free(pkt73_mbuf); +} + +static void testcase_job_bpf_match_external_and_internal(void ** state) +{ + struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); + + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 0, + .bpf_expr = "ip src 1.1.15.100", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc); + + struct dp_trace_job_desc desc_2 = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 1, + .bpf_expr = "vlan && ip src 125.33.49.137", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc_2); + + dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); + u_int16_t ret = dp_trace_job_id_bitmap_get(trace, pkt73_mbuf); + assert_true(ret == 3); + + struct dp_trace_buffer * dp_trace_buffer = (struct dp_trace_buffer *)mrb_meta->dp_trace_buffer; + assert_true(dp_trace_buffer != NULL); + assert_true(dp_trace_buffer->jobs == 3); + + infra_rte_pktmbuf_free(pkt73_mbuf); +} + +static void testcase_job_bpf_unmatch(void ** state) +{ + struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); + unsigned int offset = mrb_meta->pkt_parser_result.layers[4].offset; + + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 0, + .bpf_expr = "vlan && ip src 127.0.0.1", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc); + + dp_trace_filter_exec(trace, pkt73_mbuf, offset, 0); + u_int16_t ret = dp_trace_job_id_bitmap_get(trace, pkt73_mbuf); + assert_true(ret == 0); + + assert_true(mrb_meta->dp_trace_buffer == NULL); + + infra_rte_pktmbuf_free(pkt73_mbuf); +} + +static void testcase_job_emit_trace(void ** state) +{ + struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); + + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 1, + .bpf_expr = "ether host 64:f6:9d:5f:b9:76", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc); + + mrb_meta->packet_create_from_nf = 1; + memset(&mrb_meta->pkt_parser_result, 0, sizeof(mrb_meta->pkt_parser_result)); + + dp_trace_filter_exec(trace, pkt73_mbuf, 0, rte_lcore_id()); + + struct dp_trace_record_meta meta = {DP_TRACE_MEASUREMENT_TYPE_TRACE, "test", "emit", NULL}; + dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta, "abc"); + + struct dp_trace_record_meta meta_2 = {DP_TRACE_MEASUREMENT_TYPE_TRACE, "test", "emit", NULL}; + dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta_2, "def"); + + struct dp_trace_buffer * dp_trace_buffer = (struct dp_trace_buffer *)mrb_meta->dp_trace_buffer; + + char * cur = dp_trace_buffer->buffer; + struct dp_trace_record_header * record_header = (struct dp_trace_record_header *)(cur); + char * str = cur + sizeof(struct dp_trace_record_header); + unsigned int str_len = record_header->recode_len; + assert_true(contains_substring(str, "abc", str_len) == 1); + + cur += sizeof(struct dp_trace_record_header) + str_len; + record_header = (struct dp_trace_record_header *)(cur); + str = cur + sizeof(struct dp_trace_record_header); + assert_true(contains_substring(str, "def", str_len) == 1); + + // Excessive content will not cause buffer overflow + char big_buf[DP_TRACE_RECORD_SIZE] = {}; + memset(big_buf, 'a', DP_TRACE_RECORD_SIZE - 1); + dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta_2, big_buf); + + assert_true(dp_trace_buffer->buffer_used <= DP_TRACE_RECORD_SIZE); + + infra_rte_pktmbuf_free(pkt73_mbuf); +} + +static void testcase_job_strip_to_ring(void ** state) +{ + struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); + unsigned int offset = mrb_meta->pkt_parser_result.layers[4].offset; + + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 0, + .bpf_expr = "ether host 64:f6:9d:5f:b9:76", + .pkt_cnt_max = 10, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc); + + dp_trace_filter_exec(trace, pkt73_mbuf, offset, rte_lcore_id()); + + struct dp_trace_record_meta meta = {DP_TRACE_MEASUREMENT_TYPE_TRACE, "test", "emit", NULL}; + dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta, "abc"); + + dp_trace_record_write(trace, pkt73_mbuf, rte_lcore_id()); + + unsigned int trace_record_cnt = 0; + for (unsigned int i = 0; i < trace->nr_ring; i++) + { + trace_record_cnt += rte_ring_count(trace->ring[i]); + } + assert_true(trace_record_cnt == 1); + + infra_rte_pktmbuf_free(pkt73_mbuf); +} + +static void testcase_job_max_record_count(void ** state) +{ + unsigned int lcore_id = rte_lcore_id(); + + struct dp_trace_job_desc desc = { + .enable = true, + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, + .rule_index = 0, + .bpf_expr = "ether host 64:f6:9d:5f:b9:76", + .pkt_cnt_max = 2, + .sampling = 1, + }; + dp_trace_job_add(trace, &desc); + + struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); + infra_rte_pktmbuf_free(pkt73_mbuf); + + assert_true(trace->statistics[lcore_id].record_buf_alloc_success == 1); + + pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); + infra_rte_pktmbuf_free(pkt73_mbuf); + + assert_true(trace->statistics[lcore_id].record_buf_alloc_success == 2); + + pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); + dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); + infra_rte_pktmbuf_free(pkt73_mbuf); + + assert_true(trace->statistics[lcore_id].record_buf_alloc_success == 2); +} + +int main(int argc, char * argv[]) +{ + + const struct CMUnitTest testcase_trace[] = { + cmocka_unit_test_setup_teardown(testcase_packet_construct, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_instance_create, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_init, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_destroy, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_bpf_match, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_bpf_match_external_and_internal, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_bpf_unmatch, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_emit_trace, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_strip_to_ring, setup, teardown), + cmocka_unit_test_setup_teardown(testcase_job_max_record_count, setup, teardown), + }; + + // 0 on success, or the number of failed tests. + int ret = cmocka_run_group_tests(testcase_trace, setup_testcase, teardown_testCase); + + // Pass the return value to ctest. Report an error if it is non-zero + return ret; +} + +//////////////////////////////////// helper function //////////////////////////////////// + +int contains_substring(const char * str, const char * substr, size_t len) +{ + size_t substr_len = strlen(substr); + for (size_t i = 0; i <= len - substr_len; i++) + { + if (strncmp(&str[i], substr, substr_len) == 0) + { + return 1; + } + } + return -1; +}
\ No newline at end of file diff --git a/infra/test/TestDataPathTrace.cc b/infra/test/TestDataPathTrace.cc deleted file mode 100644 index 105b444..0000000 --- a/infra/test/TestDataPathTrace.cc +++ /dev/null @@ -1,387 +0,0 @@ - -extern "C" -{ -#include "dp_trace.h" -#include "ldbc.h" -#include "mrb_define.h" -} -#include <fstream> -#include <gtest/gtest.h> - -unsigned int g_logger_to_stdout = 1; -unsigned int g_logger_level = LOG_DEBUG; - -/** - * pkt1 - * Ethernet II, Src: aa:bb:cc:dd:ee:ff (aa:bb:cc:dd:ee:ff), Dst: CIMSYS_33:44:55 (00:11:22:33:44:55) - * Internet Protocol Version 4, Src: 19.40.193.239, Dst: 19.144.189.239 - * Transmission Control Protocol, Src Port: 47837, Dst Port: 443, Seq: 1, Ack: 1, Len: 74 - */ -static const unsigned char pkt1[140] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xaa, 0xbb, /*.."3DU.. */ - 0xcc, 0xdd, 0xee, 0xff, 0x08, 0x00, 0x45, 0x00, /* ......E. */ - 0x00, 0x7e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, /* .~..@.@. */ - 0x93, 0xe3, 0x13, 0x28, 0xc1, 0xef, 0x13, 0x90, /* ...(.... */ - 0xbd, 0xef, 0xba, 0xdd, 0x01, 0xbb, 0x9e, 0x5c, /* .......\ */ - 0x5b, 0x6c, 0xd8, 0x10, 0x6b, 0xe8, 0x80, 0x18, /* [l..k... */ - 0x08, 0x00, 0x00, 0x92, 0x00, 0x00, 0x01, 0x01, /* ........ */ - 0x08, 0x0a, 0xab, 0x88, 0x5c, 0x60, 0xd5, 0x2b, /* ....\`.+ */ - 0xfd, 0x1c, 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, /* ........ */ - 0x17, 0x03, 0x03, 0x00, 0x3f, 0x28, 0x85, 0xf5, /* ....?(.. */ - 0x83, 0x02, 0x3a, 0x42, 0x1e, 0x4a, 0x9f, 0x5a, /* ..:B.J.Z */ - 0x1f, 0x00, 0x59, 0x19, 0xaa, 0xe8, 0xc0, 0xd1, /* ..Y..... */ - 0xa6, 0xc4, 0x04, 0xc0, 0xa6, 0x1a, 0xa4, 0x02, /* ........ */ - 0x05, 0x69, 0xdc, 0x4e, 0x5f, 0x9b, 0xbb, 0x91, /* .i.N_... */ - 0xf6, 0x07, 0xc9, 0xf0, 0xe7, 0x28, 0xa7, 0xfc, /* .....(.. */ - 0xa0, 0x6a, 0xd8, 0x04, 0x8f, 0xee, 0xf4, 0x1f, /* .j...... */ - 0x0f, 0x6f, 0xc3, 0xfb, 0xbb, 0x22, 0x9a, 0xda, /* .o...".. */ - 0x84, 0x5e, 0xb0, 0xe9 /* .^.. */ -}; - -/* 73 Ether/IPv4/UDP/G-VxLan/Ether/VLAN/IPv4/TCP - - Outer Ether e8:4d:d0:ca:3a:1f -> 58:69:6c:6f:96:f3 - Outer IPv4 1.1.15.100 -> 10.0.4.120 - Outer UDP 60014 -> 4789 - - Outer Ether 64:f6:9d:5f:b9:76 -> a4:93:4c:c6:e5:5f - Inner IPv4 125.33.49.137 -> 39.66.162.89 - Inner TCP 28402→11235 -*/ - -/* Frame (114 bytes) */ -static const unsigned char pkt73[114] = { - 0xe8, 0x4d, 0xd0, 0xca, 0x3a, 0x1f, 0x58, 0x69, /* .M..:.Xi */ - 0x6c, 0x6f, 0x96, 0xf3, 0x08, 0x00, 0x45, 0x00, /* lo....E. */ - 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x11, /* .d...... */ - 0x9e, 0xac, 0x01, 0x01, 0x0f, 0x64, 0x0a, 0x00, /* .....d.. */ - 0x04, 0x78, 0xea, 0x6e, 0x12, 0xb5, 0x00, 0x50, /* .x.n...P */ - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x50, /* .......P */ - 0x01, 0x00, 0x64, 0xf6, 0x9d, 0x5f, 0xb9, 0x76, /* ..d.._.v */ - 0xa4, 0x93, 0x4c, 0xc6, 0xe5, 0x5f, 0x81, 0x00, /* ..L.._.. */ - 0x00, 0x01, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, /* ....E..( */ - 0x59, 0x6f, 0x40, 0x00, 0x7b, 0x06, 0x2e, 0x1b, /* Yo@.{... */ - 0x7d, 0x21, 0x31, 0x89, 0x27, 0x42, 0xa2, 0x59, /* }!1.'B.Y */ - 0x6e, 0xf2, 0x2b, 0xe3, 0xa5, 0x40, 0xd8, 0x7f, /* n.+..@.. */ - 0x9d, 0x5c, 0x74, 0xba, 0x50, 0x10, 0xfb, 0xb8, /* .\t.P... */ - 0x11, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .)...... */ - 0x00, 0x00 /* .. */ -}; - -class DataPathTraceTest : public testing::Test -{ - protected: - static void SetUpTestCase() - { - const char * argv[] = {"TestDataPathTrace", "-c", "0x1", "--no-huge", "-m", "512"}; - if (rte_eal_init(RTE_DIM(argv), (char **)argv) < 0) - { - rte_exit(EXIT_FAILURE, "failed at rte_eal_init()"); - } - } - - void SetUp() override - { - // create trace - trace = dp_trace_process_create(DP_TRACE_PROCESS_MARSIO); - trace->inst->enable = true; - unsigned int sz_align_priv = RTE_ALIGN(sizeof(struct mrb_metadata), RTE_MBUF_PRIV_ALIGN); - mempool = rte_pktmbuf_pool_create("dp_trace_dump_pool", 16, 0, sz_align_priv, - DP_TRACE_RECORD_SIZE + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - } - - void TearDown() override - { - dp_trace_process_destroy(trace, DP_TRACE_PROCESS_MARSIO); - } - - static void TearDownTestCase() - { - rte_eal_cleanup(); - } - - void dp_trace_process_destroy(struct dp_trace_process * trace, enum dp_trace_process_type process_tpye) - { - // This function is for unit testing only. This instance created by marsio or app should not be deleted - // manually. It accompanies the entire life cycle of the process. - if (process_tpye == DP_TRACE_PROCESS_MARSIO) - { - rte_mempool_free(trace->inst->pool); - rte_mempool_free(mempool); - for (unsigned int i = 0; i < trace->inst->nr_ring; i++) - { - rte_ring_free(trace->inst->ring[i]); - } - FREE(trace->inst); - FREE(trace); - } - else - { - FREE(trace); - } - } - - struct rte_mbuf * mbuf_construct(const unsigned char * pkt, unsigned int len) - { - if (trace == NULL) - return NULL; - - struct rte_mbuf * pkt_mbuf = rte_pktmbuf_alloc(mempool); - unsigned int sz_align_priv = RTE_ALIGN(sizeof(struct mrb_metadata), RTE_MBUF_PRIV_ALIGN); - - uint16_t data_off = sizeof(struct rte_mbuf) + sz_align_priv; - unsigned char * data_addr = (unsigned char *)pkt_mbuf->buf_addr + data_off; - memcpy(data_addr, pkt, len); - pkt_mbuf->data_off = data_off; - pkt_mbuf->data_len = len; - pkt_mbuf->pkt_len = len; - pkt_mbuf->nb_segs = 1; - pkt_mbuf->next = NULL; - - // parse mbuf - struct pkt_parser _pkt_handler; - struct pkt_parser_result _pkt_result; - pkt_parser_init(&_pkt_handler, &_pkt_result, LAYER_TYPE_ALL, MR_PKT_PARSER_LAYERS_MAX); - pkt_parser_exec(&_pkt_handler, pkt_mbuf); - - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt_mbuf, 1); - struct pkt_parser_result * pkt_parser_result = &mrb_meta->pkt_parser_result; - memcpy(pkt_parser_result, &_pkt_result, sizeof(struct pkt_parser_result)); - mrb_meta->dp_trace_buffer = NULL; - - return pkt_mbuf; - } - - struct dp_trace_process * trace; - struct rte_mempool * mempool; -}; - -TEST_F(DataPathTraceTest, PacketConstruct) -{ - struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); - - struct rte_mbuf * mbuf = (struct rte_mbuf *)rte_zmalloc(NULL, sizeof(struct rte_mbuf), 0); - mbuf->buf_len = sizeof(pkt73); - mbuf->buf_addr = (void *)(const char *)pkt73; - mbuf->data_off = 0; - mbuf->data_len = sizeof(pkt73); - mbuf->pkt_len = sizeof(pkt73); - mbuf->nb_segs = 1; - mbuf->next = NULL; - - struct pkt_parser _pkt_handler; - struct pkt_parser_result _pkt_parser; - pkt_parser_init(&_pkt_handler, &_pkt_parser, LAYER_TYPE_ALL, MR_PKT_PARSER_LAYERS_MAX); - pkt_parser_exec(&_pkt_handler, mbuf); - unsigned int inner_ether_offset = _pkt_parser.layers[4].offset; - - EXPECT_EQ(mrb_meta->pkt_parser_result.layers[4].offset, inner_ether_offset); - - FREE(mbuf); - infra_rte_pktmbuf_free(pkt73_mbuf); -} - -TEST_F(DataPathTraceTest, InstanceCreate) -{ - EXPECT_NE(trace->inst, nullptr); -} - -TEST_F(DataPathTraceTest, JobInit) -{ - int n; - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "ether host 64:f6:9d:5f:b9:76", 10, 1}; - n = dp_trace_job_add(trace, &desc); - EXPECT_GE(n, 0); - EXPECT_EQ(trace->inst->job_ctx[0].used, true); -} - -TEST_F(DataPathTraceTest, JobDestroy) -{ - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "ether host 64:f6:9d:5f:b9:76", 10, 1}; - dp_trace_job_add(trace, &desc); - - struct dp_trace_job_desc desc_2 = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 1, "vlan && ip src 125.33.49.137", 10, 1}; - dp_trace_job_add(trace, &desc_2); - - dp_trace_jobs_destroy(trace, 1 | 1 << 1); - - EXPECT_EQ(trace->inst->job_ctx[0].used, false); - EXPECT_EQ(trace->inst->job_ctx[1].used, false); -} - -TEST_F(DataPathTraceTest, BPFMatch) -{ - struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); - unsigned int offset = mrb_meta->pkt_parser_result.layers[4].offset; - - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "ether host 64:f6:9d:5f:b9:76", 10, 1}; - dp_trace_job_add(trace, &desc); - - struct dp_trace_job_desc desc_2 = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 1, "vlan && ip src 125.33.49.137", 10, 1}; - dp_trace_job_add(trace, &desc_2); - - dp_trace_filter_exec(trace, pkt73_mbuf, offset, 0); - u_int16_t ret = dp_trace_job_id_bitmap_get(trace, pkt73_mbuf); - EXPECT_EQ(ret, 3); - - struct dp_trace_buffer * dp_trace_buffer = (struct dp_trace_buffer *)mrb_meta->dp_trace_buffer; - EXPECT_TRUE(dp_trace_buffer != NULL); - EXPECT_TRUE(dp_trace_buffer->jobs == 3); - - infra_rte_pktmbuf_free(pkt73_mbuf); -} - -TEST_F(DataPathTraceTest, BPFMatchNet) -{ - struct rte_mbuf * pkt1_buf = mbuf_construct(pkt1, sizeof(pkt1)); - - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "net 0.0.0.0/0", 10, 1}; - dp_trace_job_add(trace, &desc); - - dp_trace_filter_exec(trace, pkt1_buf, 0, 0); - u_int16_t ret = dp_trace_job_id_bitmap_get(trace, pkt1_buf); - EXPECT_EQ(ret, 1); - - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt1_buf, 1); - struct dp_trace_buffer * dp_trace_buffer = (struct dp_trace_buffer *)mrb_meta->dp_trace_buffer; - - EXPECT_TRUE(dp_trace_buffer != NULL); - EXPECT_TRUE(dp_trace_buffer->jobs == 1); - - infra_rte_pktmbuf_free(pkt1_buf); -} - -TEST_F(DataPathTraceTest, BPFMatchExternalAndInternal) -{ - struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); - - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "ip src 1.1.15.100", 10, 1}; - dp_trace_job_add(trace, &desc); - - struct dp_trace_job_desc desc_2 = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 1, "vlan && ip src 125.33.49.137", 10, 1}; - dp_trace_job_add(trace, &desc_2); - - dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); - u_int16_t ret = dp_trace_job_id_bitmap_get(trace, pkt73_mbuf); - EXPECT_EQ(ret, 3); - - struct dp_trace_buffer * dp_trace_buffer = (struct dp_trace_buffer *)mrb_meta->dp_trace_buffer; - EXPECT_TRUE(dp_trace_buffer != NULL); - EXPECT_TRUE(dp_trace_buffer->jobs == 3); - - infra_rte_pktmbuf_free(pkt73_mbuf); -} - -TEST_F(DataPathTraceTest, BPFUnmatch) -{ - struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); - unsigned int offset = mrb_meta->pkt_parser_result.layers[4].offset; - - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "vlan && ip src 127.0.0.1", 10, 1}; - dp_trace_job_add(trace, &desc); - - dp_trace_filter_exec(trace, pkt73_mbuf, offset, 0); - u_int16_t ret = dp_trace_job_id_bitmap_get(trace, pkt73_mbuf); - EXPECT_EQ(ret, 0); - - EXPECT_TRUE(mrb_meta->dp_trace_buffer == NULL); - - infra_rte_pktmbuf_free(pkt73_mbuf); -} - -TEST_F(DataPathTraceTest, EmitTrace) -{ - struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); - - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 1, "ether host 64:f6:9d:5f:b9:76", 10, 1}; - dp_trace_job_add(trace, &desc); - - mrb_meta->packet_create_from_nf = 1; - memset(&mrb_meta->pkt_parser_result, 0, sizeof(mrb_meta->pkt_parser_result)); - - dp_trace_filter_exec(trace, pkt73_mbuf, 0, rte_lcore_id()); - - struct dp_trace_record_meta meta = {DP_TRACE_MEASUREMENT_TYPE_TRACE, "test", "emit", NULL}; - dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta, "abc"); - - struct dp_trace_record_meta meta_2 = {DP_TRACE_MEASUREMENT_TYPE_TRACE, "test", "emit", NULL}; - dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta_2, "def"); - - struct dp_trace_buffer * dp_trace_buffer = (struct dp_trace_buffer *)mrb_meta->dp_trace_buffer; - - char * cur = dp_trace_buffer->buffer; - struct dp_trace_record_header * record_header = (struct dp_trace_record_header *)(cur); - char * str = cur + sizeof(struct dp_trace_record_header); - unsigned int str_len = record_header->recode_len; - EXPECT_TRUE(std::string(str, str_len).find("abc") != std::string::npos); - - cur += sizeof(struct dp_trace_record_header) + str_len; - record_header = (struct dp_trace_record_header *)(cur); - str = cur + sizeof(struct dp_trace_record_header); - EXPECT_TRUE(std::string(str, str_len).find("def") != std::string::npos); - - // Excessive content will not cause buffer overflow - std::string big_buf(DP_TRACE_RECORD_SIZE, 'a'); - dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta_2, big_buf.c_str()); - - EXPECT_TRUE(dp_trace_buffer->buffer_used <= DP_TRACE_RECORD_SIZE); - - infra_rte_pktmbuf_free(pkt73_mbuf); -} - -TEST_F(DataPathTraceTest, StripToRing) -{ - struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - struct mrb_metadata * mrb_meta = (struct mrb_metadata *)mrbuf_cz_data(pkt73_mbuf, 1); - unsigned int offset = mrb_meta->pkt_parser_result.layers[4].offset; - - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "ether host 64:f6:9d:5f:b9:76", 10, 1}; - dp_trace_job_add(trace, &desc); - - dp_trace_filter_exec(trace, pkt73_mbuf, offset, rte_lcore_id()); - - struct dp_trace_record_meta meta = {DP_TRACE_MEASUREMENT_TYPE_TRACE, "test", "emit", NULL}; - dp_trace_record_emit_str(trace, pkt73_mbuf, rte_lcore_id(), &meta, "abc"); - - dp_trace_record_write(trace, pkt73_mbuf, rte_lcore_id()); - - unsigned int trace_record_cnt = 0; - for (unsigned int i = 0; i < trace->nr_ring; i++) - { - trace_record_cnt += rte_ring_count(trace->ring[i]); - } - EXPECT_TRUE(trace_record_cnt == 1); - - infra_rte_pktmbuf_free(pkt73_mbuf); -} - -TEST_F(DataPathTraceTest, MaxRecordCount) -{ - unsigned int lcore_id = rte_lcore_id(); - - struct dp_trace_job_desc desc = {true, DP_TRACE_MEASUREMENT_TYPE_TRACE, 0, "ether host 64:f6:9d:5f:b9:76", 2, 1}; - dp_trace_job_add(trace, &desc); - - struct rte_mbuf * pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); - infra_rte_pktmbuf_free(pkt73_mbuf); - - EXPECT_TRUE(trace->statistics[lcore_id].record_buf_alloc_success == 1); - - pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); - infra_rte_pktmbuf_free(pkt73_mbuf); - - EXPECT_TRUE(trace->statistics[lcore_id].record_buf_alloc_success == 2); - - pkt73_mbuf = mbuf_construct(pkt73, sizeof(pkt73)); - dp_trace_filter_exec(trace, pkt73_mbuf, 0, 0); - infra_rte_pktmbuf_free(pkt73_mbuf); - - EXPECT_TRUE(trace->statistics[lcore_id].record_buf_alloc_success == 2); -}
\ No newline at end of file |
