diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f7015d7..a93bb1a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,7 +53,7 @@ develop_build_debug_for_centos7: TESTING_VERSION_BUILD: 1 UPLOAD_SYMBOL_FILES: 1 BUILD_TYPE: Debug -# ASAN_OPTION: ADDRESS + ASAN_OPTION: ADDRESS PACKAGE: 1 PULP3_REPO_NAME: tsg-testing-x86_64.el7 PULP3_DIST_NAME: tsg-testing-x86_64.el7 @@ -71,7 +71,7 @@ develop_build_release_for_centos7: variables: TESTING_VERSION_BUILD: 1 UPLOAD_SYMBOL_FILES: 1 -# ASAN_OPTION: ADDRESS + ASAN_OPTION: ADDRESS BUILD_TYPE: RelWithDebInfo PACKAGE: 1 PULP3_REPO_NAME: tsg-testing-x86_64.el7 @@ -160,7 +160,7 @@ develop_build_debug_for_centos8: TESTING_VERSION_BUILD: 1 UPLOAD_SYMBOL_FILES: 1 BUILD_TYPE: Debug -# ASAN_OPTION: ADDRESS + ASAN_OPTION: ADDRESS PACKAGE: 1 PULP3_REPO_NAME: tsg-testing-x86_64.el8 PULP3_DIST_NAME: tsg-testing-x86_64.el8 @@ -178,7 +178,7 @@ develop_build_release_for_centos8: variables: TESTING_VERSION_BUILD: 1 UPLOAD_SYMBOL_FILES: 1 -# ASAN_OPTION: ADDRESS + ASAN_OPTION: ADDRESS BUILD_TYPE: RelWithDebInfo PACKAGE: 1 PULP3_REPO_NAME: tsg-testing-x86_64.el8 diff --git a/ci/travis.sh b/ci/travis.sh index 512995e..822b1d3 100644 --- a/ci/travis.sh +++ b/ci/travis.sh @@ -58,7 +58,7 @@ cmake3 -DCMAKE_CXX_FLAGS=$CXX_FLAGS \ -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ -DVERSION_DAILY_BUILD=$TESTING_VERSION_BUILD \ .. -make +make -j 4 if [ -n "${PACKAGE}" ]; then make package diff --git a/common/include/addr_tuple4.h b/common/include/addr_tuple4.h index 5efcce1..d7cfd6d 100644 --- a/common/include/addr_tuple4.h +++ b/common/include/addr_tuple4.h @@ -8,35 +8,35 @@ extern "C" #include - enum addr_tuple4_type - { - ADDR_TUPLE4_TYPE_V4, - ADDR_TUPLE4_TYPE_V6, - }; +enum addr_tuple4_type +{ + ADDR_TUPLE4_TYPE_V4, + ADDR_TUPLE4_TYPE_V6, +}; - struct addr_v4 - { - struct in_addr src_addr; /* network order */ - struct in_addr dst_addr; /* network order */ - }; +struct addr_v4 +{ + struct in_addr src_addr; /* network order */ + struct in_addr dst_addr; /* network order */ +}; - struct addr_v6 - { - struct in6_addr src_addr; /* network order */ - struct in6_addr dst_addr; /* network order */ - }; +struct addr_v6 +{ + struct in6_addr src_addr; /* network order */ + struct in6_addr dst_addr; /* network order */ +}; - struct addr_tuple4 +struct addr_tuple4 +{ + enum addr_tuple4_type addr_type; + in_port_t src_port; /* network order */ + in_port_t dst_port; /* network order */ + union { - enum addr_tuple4_type addr_type; - in_port_t src_port; /* network order */ - in_port_t dst_port; /* network order */ - union - { - struct addr_v4 addr_v4; - struct addr_v6 addr_v6; - }; + struct addr_v4 addr_v4; + struct addr_v6 addr_v6; }; +}; #define INIT_ADDR_V4(name, src_addr_str, src_port_num, dst_addr_str, dst_port_num) \ struct addr_tuple4 name; \ @@ -56,8 +56,9 @@ extern "C" inet_pton(AF_INET6, (src_addr_str), &(name).addr_v6.src_addr); \ inet_pton(AF_INET6, (dst_addr_str), &(name).addr_v6.dst_addr); - char *addr_tuple4_to_str(const struct addr_tuple4 *addr); - void addr_tuple4_reverse(const struct addr_tuple4 *orin, struct addr_tuple4 *out); +void addr_tuple4_copy(struct addr_tuple4 *dst, struct addr_tuple4 *src); +char *addr_tuple4_to_str(const struct addr_tuple4 *addr); +void addr_tuple4_reverse(const struct addr_tuple4 *orin, struct addr_tuple4 *out); #ifdef __cpluscplus } diff --git a/common/include/raw_packet.h b/common/include/raw_packet.h index 7943ed8..ee448af 100644 --- a/common/include/raw_packet.h +++ b/common/include/raw_packet.h @@ -90,7 +90,7 @@ int raw_packet_parser_get_most_outer_tuple4(struct raw_pkt_parser *handler, stru int raw_packet_parser_get_most_inner_address(struct raw_pkt_parser *handler, struct addr_tuple4 *addr); int raw_packet_parser_get_most_outer_address(struct raw_pkt_parser *handler, struct addr_tuple4 *addr); -uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum ldbc_method method, int dir_is_internal); +uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum ldbc_method method, int dir_is_i2e); #ifdef __cpluscplus } diff --git a/common/include/session_table.h b/common/include/session_table.h index d7a9a08..b34ee35 100644 --- a/common/include/session_table.h +++ b/common/include/session_table.h @@ -21,8 +21,8 @@ struct session_node uint64_t session_id; /* first key */ struct addr_tuple4 session_addr; /* second key */ - void *val_data; - fn_free_cb *val_freecb; + void *value; + fn_free_cb *value_free_cb; UT_hash_handle hh1; /* handle for first hash table */ UT_hash_handle hh2; /* handle for second hash table */ @@ -36,10 +36,10 @@ void session_table_reset(struct session_table *table); uint64_t session_table_count(struct session_table *table); // session_addr : deep copy -// val_data : shallow copy (malloc by user, free by val_freecb) +// value : shallow copy (malloc by user, free by value_free_cb) // return 0 : suceess // return -1 : key exists -int session_table_insert(struct session_table *table, uint64_t session_id, const struct addr_tuple4 *session_addr, void *val_data, const fn_free_cb *val_freecb); +int session_table_insert(struct session_table *table, uint64_t session_id, const struct addr_tuple4 *session_addr, void *value, const fn_free_cb *value_free_cb); // return 0 : success // return -1 : key not exists diff --git a/common/include/utils.h b/common/include/utils.h index f5de124..e2a0ddf 100644 --- a/common/include/utils.h +++ b/common/include/utils.h @@ -8,17 +8,17 @@ extern "C" #define MIN(a, b) ((a) > (b) ? (b) : (a)) -#define LOG_TAG_POLICY "POLICY" -#define LOG_TAG_UTILS "UTILS" -#define LOG_TAG_RAWPKT "RAW_PACKET" -#define LOG_TAG_CTRLPKT "CTRL_PACKET" -#define LOG_TAG_STABLE "SESSION_TABLE" -#define LOG_TAG_PKTIO "PACKET_IO" -#define LOG_TAG_METRICS "G_METRICS" -#define LOG_TAG_SF_METRICS "SF_METRICS" -#define LOG_TAG_SF_STATUS "SF_STATUS" -#define LOG_TAG_SCE "SCE" -#define LOG_TAG_TIMESTAMP "TIMESTAMP" +#define LOG_TAG_SCE "SCE" +#define LOG_TAG_POLICY "POLICY" +#define LOG_TAG_PKTIO "PACKET_IO" +#define LOG_TAG_RAWPKT "RAW_PACKET" +#define LOG_TAG_CTRLPKT "CTRL_PACKET" +#define LOG_TAG_METRICS "G_METRICS" +#define LOG_TAG_SF_METRICS "SF_METRICS" +#define LOG_TAG_SF_STATUS "SF_STATUS" +#define LOG_TAG_UTILS "UTILS" +#define LOG_TAG_HEALTH_CHECK "HEALTH_CHECK" +#define LOG_TAG_TIMESTAMP "TIMESTAMP" #define ATOMIC_INC(x) __atomic_fetch_add(x, 1, __ATOMIC_RELAXED) #define ATOMIC_DEC(x) __atomic_fetch_sub(x, 1, __ATOMIC_RELAXED) @@ -71,7 +71,7 @@ struct route_ctx int len; }; -int route_ctx_is_empty(struct route_ctx *ctx); +void route_ctx_write_once(struct route_ctx *dst, struct route_ctx *src); void route_ctx_copy(struct route_ctx *dst, struct route_ctx *src); /****************************************************************************** diff --git a/common/src/addr_tuple4.cpp b/common/src/addr_tuple4.cpp index fd60f0d..0ea325a 100644 --- a/common/src/addr_tuple4.cpp +++ b/common/src/addr_tuple4.cpp @@ -4,6 +4,24 @@ #include "addr_tuple4.h" +void addr_tuple4_copy(struct addr_tuple4 *dst, struct addr_tuple4 *src) +{ + dst->addr_type = src->addr_type; + dst->src_port = src->src_port; + dst->dst_port = src->dst_port; + + if (src->addr_type == ADDR_TUPLE4_TYPE_V4) + { + memcpy(&(dst->addr_v4.src_addr), &(src->addr_v4.src_addr), sizeof(struct in_addr)); + memcpy(&(dst->addr_v4.dst_addr), &(src->addr_v4.dst_addr), sizeof(struct in_addr)); + } + else + { + memcpy(&(dst->addr_v6.src_addr), &(src->addr_v6.src_addr), sizeof(struct addr_v6)); + memcpy(&(dst->addr_v6.dst_addr), &(src->addr_v6.dst_addr), sizeof(struct addr_v6)); + } +} + char *addr_tuple4_to_str(const struct addr_tuple4 *addr) { char *str_ret = NULL; diff --git a/common/src/raw_packet.cpp b/common/src/raw_packet.cpp index ada2c2e..d6d0713 100644 --- a/common/src/raw_packet.cpp +++ b/common/src/raw_packet.cpp @@ -272,7 +272,7 @@ int raw_packet_parser_get_most_outer_address(struct raw_pkt_parser *handler, str return -1; } -uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum ldbc_method method, int dir_is_internal) +uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum ldbc_method method, int dir_is_i2e) { uint64_t temp = 0; uint64_t hash_value = 1; @@ -333,7 +333,7 @@ uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum l switch (method) { case LDBC_METHOD_HASH_INT_IP: - if (dir_is_internal) + if (dir_is_i2e) { // outer src ip HASH_VALUE(outer_src_addr, outer_addr_len, hash_value); @@ -345,7 +345,7 @@ uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum l } break; case LDBC_METHOD_HASH_EXT_IP: - if (dir_is_internal) + if (dir_is_i2e) { // outer dst ip HASH_VALUE(outer_dst_addr, outer_addr_len, hash_value); @@ -363,7 +363,7 @@ uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum l hash_value = hash_value ^ temp; break; case LDBC_METHOD_HASH_INNERMOST_INT_IP: - if (dir_is_internal) + if (dir_is_i2e) { // innner src ip HASH_VALUE(inner_src_addr, inner_addr_len, hash_value); @@ -375,7 +375,7 @@ uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum l } break; case LDBC_METHOD_HASH_INNERMOST_EXT_IP: - if (dir_is_internal) + if (dir_is_i2e) { // innner dst ip HASH_VALUE(inner_dst_addr, inner_addr_len, hash_value); @@ -393,7 +393,7 @@ uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum l char *inner_addr_str = addr_tuple4_to_str(&inner_addr); char *outer_addr_str = addr_tuple4_to_str(&outer_addr); LOG_DEBUG("%s: pkt_trace_id: %lu, outer_addr: %s, inner_addr: %s, is_internal: %d, hash_method: %s, hash_value: %lu", - LOG_TAG_RAWPKT, handler->pkt_trace_id, outer_addr_str, inner_addr_str, dir_is_internal, ldbc_method_to_string(method), hash_value); + LOG_TAG_RAWPKT, handler->pkt_trace_id, outer_addr_str, inner_addr_str, dir_is_i2e, ldbc_method_to_string(method), hash_value); free(inner_addr_str); free(outer_addr_str); @@ -814,7 +814,7 @@ static const void *parse_vxlan(struct raw_pkt_parser *handler, const void *data, return data; } - struct vxlan_hdr *vxlan_hdr = (struct vxlan_hdr *)data; + // struct vxlan_hdr *vxlan_hdr = (struct vxlan_hdr *)data; uint16_t hdr_len = sizeof(struct vxlan_hdr); const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; diff --git a/common/src/session_table.cpp b/common/src/session_table.cpp index c0f35a8..1bbbfd3 100644 --- a/common/src/session_table.cpp +++ b/common/src/session_table.cpp @@ -2,7 +2,6 @@ #include "session_table.h" #include "utils.h" -#include "log.h" struct session_table { @@ -33,9 +32,9 @@ void session_table_destory(struct session_table *table) HASH_DELETE(hh1, table->root_by_id, node); HASH_DELETE(hh2, table->root_by_addr, node); - if (node->val_freecb && node->val_data) + if (node->value_free_cb && node->value) { - node->val_freecb(node->val_data); + node->value_free_cb(node->value); } free(node); @@ -58,9 +57,9 @@ void session_table_reset(struct session_table *table) HASH_DELETE(hh1, table->root_by_id, node); HASH_DELETE(hh2, table->root_by_addr, node); - if (node->val_freecb && node->val_data) + if (node->value_free_cb && node->value) { - node->val_freecb(node->val_data); + node->value_free_cb(node->value); } free(node); @@ -84,14 +83,13 @@ uint64_t session_table_count(struct session_table *table) } // session_addr : deep copy -// val_data : shallow copy (malloc by user, free by val_freecb) -int session_table_insert(struct session_table *table, uint64_t session_id, const struct addr_tuple4 *session_addr, void *val_data, const fn_free_cb *val_freecb) +// value : shallow copy (malloc by user, free by value_free_cb) +int session_table_insert(struct session_table *table, uint64_t session_id, const struct addr_tuple4 *session_addr, void *value, const fn_free_cb *value_free_cb) { struct session_node *temp = NULL; HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp); if (temp) { - LOG_DEBUG("%s: insert: key %lu exists", LOG_TAG_STABLE, session_id); return -1; } @@ -100,13 +98,12 @@ int session_table_insert(struct session_table *table, uint64_t session_id, const temp->session_id = session_id; memcpy(&temp->session_addr, session_addr, sizeof(struct addr_tuple4)); - temp->val_data = val_data; - temp->val_freecb = val_freecb; + temp->value = value; + temp->value_free_cb = value_free_cb; HASH_ADD(hh1, table->root_by_id, session_id, sizeof(temp->session_id), temp); HASH_ADD(hh2, table->root_by_addr, session_addr, sizeof(temp->session_addr), temp); - LOG_DEBUG("%s: insert: key %lu success", LOG_TAG_STABLE, session_id); table->session_node_count++; return 0; @@ -118,23 +115,21 @@ int session_table_delete_by_id(struct session_table *table, uint64_t session_id) HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp); if (!temp) { - LOG_DEBUG("%s: delete: key %lu not exists", LOG_TAG_STABLE, session_id); return -1; } HASH_DELETE(hh1, table->root_by_id, temp); HASH_DELETE(hh2, table->root_by_addr, temp); - if (temp->val_freecb && temp->val_data) + if (temp->value_free_cb && temp->value) { - temp->val_freecb(temp->val_data); - temp->val_data = NULL; + temp->value_free_cb(temp->value); + temp->value = NULL; } free(temp); temp = NULL; - LOG_DEBUG("%s: delete: key %lu success", LOG_TAG_STABLE, session_id); table->session_node_count--; return 0; @@ -143,7 +138,6 @@ int session_table_delete_by_id(struct session_table *table, uint64_t session_id) int session_table_delete_by_addr(struct session_table *table, const struct addr_tuple4 *session_addr) { struct session_node *temp = NULL; - char *addr_str = addr_tuple4_to_str(session_addr); HASH_FIND(hh2, table->root_by_addr, session_addr, sizeof(struct addr_tuple4), temp); if (!temp) { @@ -152,8 +146,6 @@ int session_table_delete_by_addr(struct session_table *table, const struct addr_ HASH_FIND(hh2, table->root_by_addr, &reverse_addr, sizeof(struct addr_tuple4), temp); if (!temp) { - LOG_DEBUG("%s: delete: key %s not exists", LOG_TAG_STABLE, addr_str); - free(addr_str); return -1; } } @@ -161,18 +153,15 @@ int session_table_delete_by_addr(struct session_table *table, const struct addr_ HASH_DELETE(hh1, table->root_by_id, temp); HASH_DELETE(hh2, table->root_by_addr, temp); - if (temp->val_freecb && temp->val_data) + if (temp->value_free_cb && temp->value) { - temp->val_freecb(temp->val_data); - temp->val_data = NULL; + temp->value_free_cb(temp->value); + temp->value = NULL; } free(temp); temp = NULL; - LOG_DEBUG("%s: delete: key %s success", LOG_TAG_STABLE, addr_str); - free(addr_str); - addr_str = NULL; table->session_node_count--; return 0; @@ -184,19 +173,15 @@ struct session_node *session_table_search_by_id(struct session_table *table, uin HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp); if (!temp) { - LOG_DEBUG("%s: search: key %lu not exists", LOG_TAG_STABLE, session_id); return NULL; } - LOG_DEBUG("%s: search: key %lu success", LOG_TAG_STABLE, session_id); - return temp; } struct session_node *session_table_search_by_addr(struct session_table *table, const struct addr_tuple4 *session_addr) { struct session_node *temp = NULL; - char *addr_str = addr_tuple4_to_str(session_addr); HASH_FIND(hh2, table->root_by_addr, session_addr, sizeof(struct addr_tuple4), temp); if (!temp) { @@ -205,16 +190,9 @@ struct session_node *session_table_search_by_addr(struct session_table *table, c HASH_FIND(hh2, table->root_by_addr, &reverse_addr, sizeof(struct addr_tuple4), temp); if (!temp) { - LOG_DEBUG("%s: search: key %s not exists", LOG_TAG_STABLE, addr_str); - free(addr_str); - addr_str = NULL; return NULL; } } - LOG_DEBUG("%s: search: key %s success", LOG_TAG_STABLE, addr_str); - free(addr_str); - addr_str = NULL; - return temp; } diff --git a/common/src/timestamp.cpp b/common/src/timestamp.cpp index 6dc0cbb..a553322 100644 --- a/common/src/timestamp.cpp +++ b/common/src/timestamp.cpp @@ -20,9 +20,9 @@ struct timestamp *timestamp_new(uint64_t update_interval_ms) ts->update_interval_ms = update_interval_ms; timestamp_update(ts); - LOG_DEBUG("%s: TIMESTAMP->update_interval_ms : %lu", LOG_TAG_TIMESTAMP, timestamp_update_interval_ms(ts)); - LOG_DEBUG("%s: TIMESTAMP->current_sec : %lu", LOG_TAG_TIMESTAMP, timestamp_get_sec(ts)); - LOG_DEBUG("%s: TIMESTAMP->current_msec : %lu", LOG_TAG_TIMESTAMP, timestamp_get_msec(ts)); + LOG_DEBUG("%s: TIMESTAMP->update_interval_ms : %lu", LOG_TAG_TIMESTAMP, timestamp_update_interval_ms(ts)); + LOG_DEBUG("%s: TIMESTAMP->current_sec : %lu", LOG_TAG_TIMESTAMP, timestamp_get_sec(ts)); + LOG_DEBUG("%s: TIMESTAMP->current_msec : %lu", LOG_TAG_TIMESTAMP, timestamp_get_msec(ts)); return ts; } diff --git a/common/src/utils.cpp b/common/src/utils.cpp index 29c3318..56bb951 100644 --- a/common/src/utils.cpp +++ b/common/src/utils.cpp @@ -126,15 +126,14 @@ void sids_copy(struct sids *dst, struct sids *src) * route_ctx ******************************************************************************/ -int route_ctx_is_empty(struct route_ctx *ctx) +void route_ctx_write_once(struct route_ctx *dst, struct route_ctx *src) { - if (ctx->len == 0) + if (dst && src) { - return 1; - } - else - { - return 0; + if (dst->len == 0) + { + route_ctx_copy(dst, src); + } } } @@ -150,8 +149,8 @@ void route_ctx_copy(struct route_ctx *dst, struct route_ctx *src) void throughput_metrics_inc(struct throughput_metrics *iterm, uint64_t n_pkts, uint64_t n_bytes) { - __atomic_fetch_add(&iterm->n_bytes, n_bytes, __ATOMIC_RELAXED); - __atomic_fetch_add(&iterm->n_pkts, n_pkts, __ATOMIC_RELAXED); + ATOMIC_ADD(&iterm->n_bytes, n_bytes); + ATOMIC_ADD(&iterm->n_pkts, n_pkts); } /****************************************************************************** diff --git a/common/test/gtest_ctrl_packet.cpp b/common/test/gtest_ctrl_packet.cpp index 3f8365d..2af2f7b 100644 --- a/common/test/gtest_ctrl_packet.cpp +++ b/common/test/gtest_ctrl_packet.cpp @@ -4,7 +4,7 @@ TEST(CTRL_PACKET, PARSE) { - const char *data = "{\"tsync\":\"1.0\",\"session_id\":123456789,\"state\":\"active\",\"method\":\"policy_update\",\"params\":{\"service_chaining\":[1,2,3],\"shaping\":[4,5,6]}}"; + const char *data = "{\"tsync\":\"1.0\",\"session_id\":\"123456789\",\"state\":\"active\",\"method\":\"policy_update\",\"params\":{\"service_chaining\":[1,2,3],\"shaping\":[4,5,6]}}"; size_t length = strlen(data); struct ctrl_pkt_parser parser; diff --git a/common/test/gtest_session_table.cpp b/common/test/gtest_session_table.cpp index 5850160..a804454 100644 --- a/common/test/gtest_session_table.cpp +++ b/common/test/gtest_session_table.cpp @@ -48,10 +48,10 @@ TEST(STREAM_TABLE, SEARCH_BY_ID) struct session_node *node = NULL; node = session_table_search_by_id(table, 1); EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->val_data, "HELLO"); + EXPECT_STREQ((const char *)node->value, "HELLO"); node = session_table_search_by_id(table, 2); EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->val_data, "WORLD"); + EXPECT_STREQ((const char *)node->value, "WORLD"); node = session_table_search_by_id(table, 3); EXPECT_TRUE(node == nullptr); @@ -80,10 +80,10 @@ TEST(STREAM_TABLE, SEARCH_BY_ADDR) struct session_node *node = NULL; node = session_table_search_by_addr(table, &addr1); EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->val_data, "HELLO"); + EXPECT_STREQ((const char *)node->value, "HELLO"); node = session_table_search_by_addr(table, &addr2); EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->val_data, "WORLD"); + EXPECT_STREQ((const char *)node->value, "WORLD"); node = session_table_search_by_addr(table, &addr3); EXPECT_TRUE(node == nullptr); @@ -115,10 +115,10 @@ TEST(STREAM_TABLE, SEARCH_BY_REVERSE_ADDR) struct session_node *node = NULL; node = session_table_search_by_addr(table, &addr1_reverse); EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->val_data, "HELLO"); + EXPECT_STREQ((const char *)node->value, "HELLO"); node = session_table_search_by_addr(table, &addr2_reverse); EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->val_data, "WORLD"); + EXPECT_STREQ((const char *)node->value, "WORLD"); // TEST Destory session_table_destory(table); diff --git a/conf/sce.conf b/conf/sce.conf index f47108b..a2b37e1 100644 --- a/conf/sce.conf +++ b/conf/sce.conf @@ -3,6 +3,7 @@ nr_worker_threads=8 cpu_affinity_mask=2,3,4-9 firewall_sids=1001 enable_debug=0 +enable_send_log=0 ts_update_interval_ms=1 # Only when (disable_coredump == 1 || (enable_breakpad == 1 && enable_breakpad_upload == 1)) is satisfied, the core will not be generated locally diff --git a/platform/include/global_metrics.h b/platform/include/global_metrics.h index 4771136..2d9eb3c 100644 --- a/platform/include/global_metrics.h +++ b/platform/include/global_metrics.h @@ -9,7 +9,7 @@ extern "C" #include "utils.h" #include -struct global_metrics_config +struct metrics_config { char output_file[256]; char statsd_server[32]; @@ -21,42 +21,78 @@ struct global_metrics_config char prometheus_listen_url[256]; }; +struct device_metrics +{ + struct throughput_metrics nf_rx; // 累计值 + struct throughput_metrics nf_tx; // 累计值 + + struct throughput_metrics endpoint_rx; // 累计值 + struct throughput_metrics endpoint_tx; // 累计值 + struct throughput_metrics endpoint_drop; // 累计值 +}; + +// raw_pkt_metrics 不包含 g_vxlan 所占的字节 +struct raw_pkt_metrics +{ + struct throughput_metrics mirr_bypass; // 累计值 + struct throughput_metrics mirr_block; // 累计值 + struct throughput_metrics mirr_rx_drop; // 累计值 + struct throughput_metrics mirr_tx; // 累计值 + + struct throughput_metrics stee_bypass; // 累计值 + struct throughput_metrics stee_block; // 累计值 + struct throughput_metrics stee_rx; // 累计值 + struct throughput_metrics stee_tx; // 累计值 + + struct throughput_metrics miss_sess; // 累计值 + struct throughput_metrics error_bypass; // 累计值 + struct throughput_metrics error_block; // 累计值 +}; + +struct ctrl_pkt_metrics +{ + struct throughput_metrics rx; // 累计值 + struct throughput_metrics tx; // 累计值 + + uint64_t opening; // 累计值 + uint64_t active; // 累计值 + uint64_t closing; // 累计值 + uint64_t resetall; // 累计值 + uint64_t error; // 累计值 +}; + +struct keepalived_pkt_metrics +{ + struct throughput_metrics downlink_rx; // 累计值 + struct throughput_metrics downlink_tx; // 累计值 + + struct throughput_metrics uplink_rx; // 累计值 + struct throughput_metrics uplink_tx_drop; // 累计值 +}; + +struct sf_status_metrics +{ + uint64_t active; // 累计值 + uint64_t inactive; // 累计值 +}; + +struct sf_session_metrics +{ + uint64_t num; // 当前值 + uint64_t log; // 累计值 +}; + struct global_metrics { - struct throughput_metrics dev_endpoint_rx; // 累计值 - struct throughput_metrics dev_endpoint_tx; // 累计值 - struct throughput_metrics dev_endpoint_err_drop; // 累计值 + struct device_metrics device; + struct raw_pkt_metrics raw_pkt; + struct ctrl_pkt_metrics ctrl_pkt; + struct keepalived_pkt_metrics kee_pkt; - struct throughput_metrics raw_pkt_rx; // 累计值 - struct throughput_metrics raw_pkt_tx; // 累计值 - struct throughput_metrics raw_pkt_err_bypass; // 累计值 + struct sf_status_metrics sf_status; + struct sf_session_metrics sf_session; - struct throughput_metrics hit_block_policy; // 累计值 - struct throughput_metrics hit_bypass_policy; // 累计值 - - struct throughput_metrics steering_tx; // 累计值 - struct throughput_metrics steering_rx; // 累计值 - - struct throughput_metrics mirroring_tx; // 累计值 - struct throughput_metrics mirroring_rx_drop; // 累计值 - - struct throughput_metrics downlink_keepalive_pkt_rx; // 累计值 - struct throughput_metrics uplink_keepalive_pkt_rx; // 累计值 - struct throughput_metrics ctrl_pkt_rx; // 累计值 - - uint64_t ctrl_pkt_opening_num; // 累计值 - uint64_t ctrl_pkt_active_num; // 累计值 - uint64_t ctrl_pkt_closing_num; // 累计值 - uint64_t ctrl_pkt_resetall_num; // 累计值 - uint64_t ctrl_pkt_error_num; // 累计值 - - uint64_t sf_active_times; // 累计值 - uint64_t sf_inactive_times; // 累计值 - - uint64_t session_nums; // 瞬时值 - uint64_t send_log; // 瞬时值 - - struct global_metrics_config config; + struct metrics_config config; screen_stat_handle_t fs_handle; int fs_id[128]; }; diff --git a/platform/include/packet_io.h b/platform/include/packet_io.h index 7ab522b..dc86c27 100644 --- a/platform/include/packet_io.h +++ b/platform/include/packet_io.h @@ -12,8 +12,8 @@ void packet_io_destory(struct packet_io *handle); int packet_io_thread_init(struct packet_io *handle, struct thread_ctx *thread_ctx); void packet_io_thread_wait(struct packet_io *handle, struct thread_ctx *thread_ctx, int timeout_ms); -int packet_io_polling_nf_interface(struct packet_io *handle, int thread_seq, void *ctx); -int packet_io_polling_endpoint(struct packet_io *handle, int thread_seq, void *ctx); +int packet_io_thread_polling_nf(struct packet_io *handle, struct thread_ctx *thread_ctx); +int packet_io_thread_polling_endpoint(struct packet_io *handle, struct thread_ctx *thread_ctx); #ifdef __cpluscplus } diff --git a/platform/include/policy.h b/platform/include/policy.h index dd7bccf..58bbd38 100644 --- a/platform/include/policy.h +++ b/platform/include/policy.h @@ -30,19 +30,18 @@ enum session_action SESSION_ACTION_BLOCK = 2, }; -enum session_action_reason +enum action_reason { ACTION_BYPASS_DUE_DEFAULT = 0x00, + ACTION_BYPASS_DUE_INVALID_POLICY = 0x01, + ACTION_BYPASS_DUE_FAILURE_ACTION = 0x02, + ACTION_BYPASS_DUE_UNAVAILABLE_ACTION = 0x03, + ACTION_BYPASS_DUE_HEALTH_SF_LIMIT = 0x04, - ACTION_BYPASS_DUE_HEALTH_SF_LIMIT = 0x12, - ACTION_BYPASS_DUE_UNAVAILABLE_ACTION = 0x13, - ACTION_BYPASS_DUE_FAILURE_ACTION = 0x14, - ACTION_BYPASS_DUE_INVALID_POLICY = 0x15, + ACTION_BLOCK_DUE_FAILURE_ACTION = 0x10, + ACTION_BLOCK_DUE_UNAVAILABLE_ACTION = 0x11, - ACTION_BLOCK_DUE_UNAVAILABLE_ACTION = 0x21, - ACTION_BLOCK_DUE_FAILURE_ACTION = 0x22, - - ACTION_FORWAED_DUE_SELECTED_AVAILABLE_SF = 0x31, + ACTION_FORWAED_DUE_SELECTED_SF = 0x20, }; enum package_method @@ -90,7 +89,7 @@ struct selected_sf int sf_need_skip; int sf_profile_id; enum session_action sf_action; - enum session_action_reason sf_action_reason; + enum action_reason sf_action_reason; struct connectivity sf_connectivity; struct throughput_metrics rx; @@ -106,8 +105,29 @@ struct selected_chaining struct selected_sf *chaining; int chaining_size; int chaining_used; + + uint64_t session_id; + char *session_addr; }; +struct selected_chainings +{ + struct selected_chaining *chaining_raw; + struct selected_chaining *chaining_decrypted; +}; + +const char *traffic_type_to_string(enum traffic_type traffic_type); +const char *forward_type_to_string(enum forward_type forward_type); +const char *session_action_to_string(enum session_action session_action); +const char *action_reason_to_string(enum action_reason action_reason); +const char *package_method_to_string(enum package_method package_method); + +struct selected_chaining *selected_chaining_create(int chaining_size, uint64_t session_id, char *session_addr); +void selected_chaining_destory(struct selected_chaining *chaining); +void selected_chaining_dump(struct selected_chaining *chaining); +void selected_chaining_bref(struct selected_chaining *chaining); +void selected_chaining_uniq(struct selected_chaining *chaining); + // return NULL : error // return !NULL : success struct policy_enforcer *policy_enforcer_create(const char *instance, const char *profile, int thread_num, void *logger); @@ -116,15 +136,8 @@ void policy_enforcer_destory(struct policy_enforcer *enforcer); // return 0 : success // return -1 : error int policy_enforcer_register(struct policy_enforcer *enforcer); -int policy_enforce_max_chaining_size(struct policy_enforcer *enforcer); - -struct selected_chaining *selected_chaining_create(int chaining_size); -void selected_chaining_destory(struct selected_chaining *chaining); -void selected_chaining_dump(struct selected_chaining *chaining); -void selected_chaining_bref(struct selected_chaining *chaining); - -const char *session_action_reason_to_string(enum session_action_reason session_action_reason); -void policy_enforce_select_chaining(struct selected_chaining *chaining, struct policy_enforcer *enforcer, struct raw_pkt_parser *parser, int policy_id, int dir_is_internal, struct session_ctx *s_ctx); +int policy_enforce_chaining_size(struct policy_enforcer *enforcer); +void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct raw_pkt_parser *parser, int policy_id, int dir_is_i2e); #ifdef __cpluscplus } diff --git a/platform/include/sce.h b/platform/include/sce.h index 2923a41..768b04a 100644 --- a/platform/include/sce.h +++ b/platform/include/sce.h @@ -15,85 +15,100 @@ extern "C" #define MAX_THREAD_NUM 128 - /****************************************************************************** - * Struct For Thread - ******************************************************************************/ +/****************************************************************************** + * Struct Thread Ctx + ******************************************************************************/ - struct thread_ctx - { - pthread_t tid; - int thread_index; - struct session_table *session_table; - struct sf_metrics *sf_metrics; +struct thread_ctx +{ + pthread_t tid; + int thread_index; - struct packet_io *ref_io; - struct global_metrics *ref_metrics; - struct policy_enforcer *ref_enforcer; - struct sce_ctx *ref_sce_ctx; + struct sf_metrics *sf_metrics; + struct session_table *session_table; - int session_table_need_reset; - }; + struct packet_io *ref_io; + struct sce_ctx *ref_sce_ctx; + struct global_metrics *ref_metrics; + struct policy_enforcer *ref_enforcer; - /****************************************************************************** - * Struct For Session - ******************************************************************************/ + int session_table_need_reset; +}; - struct packet_info - { - int dir_is_e2i; - struct addr_tuple4 tuple4; - char *addr_string; +/****************************************************************************** + * Struct Metadata + ******************************************************************************/ - char *header_data; - int header_len; +struct metadata +{ + int write_ref; + uint64_t session_id; - struct sids sids; - struct route_ctx route_ctx; - }; + char *raw_data; + int raw_len; + uint16_t l7offset; - struct session_ctx - { - struct fixed_num_array policy_ids; - uint64_t session_id; + int is_e2i_dir; + int is_ctrl_pkt; + int is_decrypted; - struct route_ctx raw_pkt_i2e_route_ctx; - struct route_ctx raw_pkt_e2i_route_ctx; + struct sids sids; + struct route_ctx route_ctx; +}; - struct sids raw_pkt_i2e_sids; - struct sids raw_pkt_e2i_sids; +struct metadata *metadata_new(); +int metadata_is_empty(struct metadata *meta); +void metadata_deep_copy(struct metadata *dst, struct metadata *src); +void metadata_shadow_copy(struct metadata *dst, struct metadata *src); +void metadata_free(struct metadata *meta); - // depending on first control packet - struct packet_info first_ctrl_pkt; - struct selected_chaining *chaining; +/****************************************************************************** + * Struct Session Ctx + ******************************************************************************/ - struct thread_ctx *ref_thread_ctx; - }; +struct session_ctx +{ + uint64_t session_id; + char *session_addr; - struct session_ctx *session_ctx_new(); - void session_ctx_free(struct session_ctx *ctx); + struct addr_tuple4 inner_tuple4; + struct fixed_num_array policy_ids; - /****************************************************************************** - * Struct For SCE - ******************************************************************************/ + struct metadata *raw_meta_i2e; + struct metadata *raw_meta_e2i; + struct metadata *ctrl_meta; - struct sce_ctx - { - int enable_debug; - int firewall_sids; - int nr_worker_threads; - int ts_update_interval_ms; - int cpu_affinity_mask[MAX_THREAD_NUM]; + struct selected_chainings chainings; - cpu_set_t coremask; - struct timestamp *ts; - struct packet_io *io; - struct global_metrics *metrics; - struct policy_enforcer *enforcer; - struct thread_ctx work_threads[MAX_THREAD_NUM]; - }; + struct thread_ctx *ref_thread_ctx; +}; - struct sce_ctx *sce_ctx_create(const char *profile); - void sce_ctx_destory(struct sce_ctx *ctx); +struct session_ctx *session_ctx_new(); +void session_ctx_free(struct session_ctx *ctx); + +/****************************************************************************** + * Struct SCE Ctx + ******************************************************************************/ + +struct sce_ctx +{ + int enable_debug; + int enable_send_log; + int firewall_sids; + int nr_worker_threads; + int ts_update_interval_ms; + int cpu_affinity_mask[MAX_THREAD_NUM]; + + cpu_set_t coremask; + struct timestamp *ts; + struct packet_io *io; + struct global_metrics *metrics; + struct policy_enforcer *enforcer; + struct thread_ctx work_threads[MAX_THREAD_NUM]; +}; + +struct sce_ctx *sce_ctx_create(const char *profile); +void sce_ctx_destory(struct sce_ctx *ctx); #ifdef __cpluscplus } diff --git a/platform/src/global_metrics.cpp b/platform/src/global_metrics.cpp index 4387552..dbc2e5d 100644 --- a/platform/src/global_metrics.cpp +++ b/platform/src/global_metrics.cpp @@ -8,49 +8,75 @@ enum SCE_STAT_FIELD { - // dev endpoint - STAT_ENDPOINT_RX_PKT, - STAT_ENDPOINT_RX_B, + // device_metrics + STAT_DEVICE_NF_RX_PKT, + STAT_DEVICE_NF_RX_B, - STAT_ENDPOINT_TX_PKT, - STAT_ENDPOINT_TX_B, + STAT_DEVICE_NF_TX_PKT, + STAT_DEVICE_NF_TX_B, - STAT_ENDPOINT_ERR_DROP_PKT, - STAT_ENDPOINT_ERR_DROP_B, + STAT_DEVICE_ENDPOINT_RX_PKT, + STAT_DEVICE_ENDPOINT_RX_B, - // hit block policy - STAT_HIT_BLOCK_POLICY_PKT, - STAT_HIT_BLOCK_POLICY_B, + STAT_DEVICE_ENDPOINT_TX_PKT, + STAT_DEVICE_ENDPOINT_TX_B, - // dev nf interface - STAT_RAW_PKT_RX_PKT, - STAT_RAW_PKT_RX_B, + // keepalived_pkt_metrics + STAT_KEE_PKT_DOWN_RX_PKT, + STAT_KEE_PKT_DOWN_RX_B, - STAT_RAW_PKT_TX_PKT, - STAT_RAW_PKT_TX_B, + STAT_KEE_PKT_DOWN_TX_PKT, + STAT_KEE_PKT_DOWN_TX_B, - STAT_RAW_PKT_ERR_BYPASS_PKT, - STAT_RAW_PKT_ERR_BYPASS_B, + STAT_KEE_PKT_UP_RX_PKT, + STAT_KEE_PKT_UP_RX_B, - // hit bypass policy - STAT_HIT_BYPASS_POLICY_PKT, - STAT_HIT_BYPASS_POLICY_B, + STAT_KEE_PKT_UP_TX_DROP_PKT, + STAT_KEE_PKT_UP_TX_DROP_B, - // steering - STAT_STEERING_TX_PKT, - STAT_STEERING_TX_B, - STAT_STEERING_RX_PKT, - STAT_STEERING_RX_B, + // raw_pkt_metrics + STAT_RAW_PKT_MIRR_BYPASS_PKT, + STAT_RAW_PKT_MIRR_BYPASS_B, - // mirroring - STAT_MIRRORING_TX_PKT, - STAT_MIRRORING_TX_B, - STAT_MIRRORING_RX_DROP_PKT, - STAT_MIRRORING_RX_DROP_B, + STAT_RAW_PKT_MIRR_BLOCK_PKT, + STAT_RAW_PKT_MIRR_BLOCK_B, - // control packet - STAT_CONTROL_RX_PKT, - STAT_CONTROL_RX_B, + STAT_RAW_PKT_MIRR_RX_DROP_PKT, + STAT_RAW_PKT_MIRR_RX_DROP_B, + + STAT_RAW_PKT_MIRR_TX_PKT, + STAT_RAW_PKT_MIRR_TX_B, + + STAT_RAW_PKT_STEE_BYPASS_PKT, + STAT_RAW_PKT_STEE_BYPASS_B, + + STAT_RAW_PKT_STEE_BLOCK_PKT, + STAT_RAW_PKT_STEE_BLOCK_B, + + STAT_RAW_PKT_STEE_RX_PKT, + STAT_RAW_PKT_STEE_RX_B, + + STAT_RAW_PKT_STEE_TX_PKT, + STAT_RAW_PKT_STEE_TX_B, + + STAT_RAW_PKT_MISS_SESS_PKT, + STAT_RAW_PKT_MISS_SESS_B, + + STAT_RAW_PKT_ERROR_BYPASS_PKT, + STAT_RAW_PKT_ERROR_BYPASS_B, + + STAT_RAW_PKT_ERROR_BLOCK_PKT, + STAT_RAW_PKT_ERROR_BLOCK_B, + + STAT_DEVICE_ENDPOINT_DROP_PKT, + STAT_DEVICE_ENDPOINT_DROP_B, + + // ctrl_pkt_metrics + STAT_CTRL_PKT_RX_PKT, + STAT_CTRL_PKT_RX_B, + + STAT_CTRL_PKT_TX_PKT, + STAT_CTRL_PKT_TX_B, STAT_CTRL_PKT_OPENING, STAT_CTRL_PKT_ACTIVE, @@ -58,21 +84,13 @@ enum SCE_STAT_FIELD STAT_CTRL_PKT_RESETALL, STAT_CTRL_PKT_ERROR, - // current session number - STAT_CURRENT_SESSION_NUMS, + // sf_session_metrics + STAT_SF_SESSION_NUM, + STAT_SF_SESSION_LOG, - // keepalive packet - STAT_DOWNLINK_KEEPALIVE_RX_PKT, - STAT_DOWNLINK_KEEPALIVE_RX_B, - STAT_UPLINK_KEEPALIVE_RX_PKT, - STAT_UPLINK_KEEPALIVE_RX_B, - - // health check - STAT_SF_ACTIVE_TIMES, - STAT_SF_INACTIVE_TIMES, - - // send log - STAT_SEND_LOG, + // sf_status_metrics + STAT_SF_STATUS_ACTIVE, + STAT_SF_STATUS_INACTIVE, // max STAT_MAX, @@ -80,75 +98,93 @@ enum SCE_STAT_FIELD static const char *stat_map[] = { - // dev endpoint - [STAT_ENDPOINT_RX_PKT] = "endp_rx_pkt", - [STAT_ENDPOINT_RX_B] = "endp_rx_B", + // device_metrics + [STAT_DEVICE_NF_RX_PKT] = "nf_rx_pkt", + [STAT_DEVICE_NF_RX_B] = "nf_rx_B", - [STAT_ENDPOINT_TX_PKT] = "endp_tx_pkt", - [STAT_ENDPOINT_TX_B] = "endp_tx_B", + [STAT_DEVICE_NF_TX_PKT] = "nf_tx_pkt", + [STAT_DEVICE_NF_TX_B] = "nf_tx_B", - [STAT_ENDPOINT_ERR_DROP_PKT] = "endp_edrop_pkt", - [STAT_ENDPOINT_ERR_DROP_B] = "endp_edrop_B", + [STAT_DEVICE_ENDPOINT_RX_PKT] = "endp_rx_pkt", + [STAT_DEVICE_ENDPOINT_RX_B] = "endp_rx_B", - // hit block policy - [STAT_HIT_BLOCK_POLICY_PKT] = "hit_block_pkt", - [STAT_HIT_BLOCK_POLICY_B] = "hit_block_B", + [STAT_DEVICE_ENDPOINT_TX_PKT] = "endp_tx_pkt", + [STAT_DEVICE_ENDPOINT_TX_B] = "endp_tx_B", - // dev nf interface - [STAT_RAW_PKT_RX_PKT] = "raw_rx_pkt", - [STAT_RAW_PKT_RX_B] = "raw_rx_B", + // keepalived_pkt_metrics + [STAT_KEE_PKT_DOWN_RX_PKT] = "kee_d_rx_pkt", + [STAT_KEE_PKT_DOWN_RX_B] = "kee_d_rx_B", - [STAT_RAW_PKT_TX_PKT] = "raw_tx_pkt", - [STAT_RAW_PKT_TX_B] = "raw_tx_B", + [STAT_KEE_PKT_DOWN_TX_PKT] = "kee_d_tx_pkt", + [STAT_KEE_PKT_DOWN_TX_B] = "kee_d_tx_B", - [STAT_RAW_PKT_ERR_BYPASS_PKT] = "raw_ebypass_pkt", - [STAT_RAW_PKT_ERR_BYPASS_B] = "raw_ebypass_B", + [STAT_KEE_PKT_UP_RX_PKT] = "kee_u_rx_pkt", + [STAT_KEE_PKT_UP_RX_B] = "kee_u_rx_B", - // hit bypass policy - [STAT_HIT_BYPASS_POLICY_PKT] = "hit_bypass_pkt", - [STAT_HIT_BYPASS_POLICY_B] = "hit_bypass_B", + [STAT_KEE_PKT_UP_TX_DROP_PKT] = "kee_u_rxdop_pkt", + [STAT_KEE_PKT_UP_TX_DROP_B] = "kee_u_rxdop_B", - // steering - [STAT_STEERING_TX_PKT] = "stee_tx_pkt", - [STAT_STEERING_TX_B] = "stee_tx_B", - [STAT_STEERING_RX_PKT] = "stee_rx_pkt", - [STAT_STEERING_RX_B] = "stee_rx_B", + // raw_pkt_metrics + [STAT_RAW_PKT_MIRR_BYPASS_PKT] = "mirr_bypass_pkt", + [STAT_RAW_PKT_MIRR_BYPASS_B] = "mirr_bypass_B", - // mirroring - [STAT_MIRRORING_TX_PKT] = "mirr_tx_pkt", - [STAT_MIRRORING_TX_B] = "mirr_tx_B", - [STAT_MIRRORING_RX_DROP_PKT] = "mirr_rx_dop_pkt", - [STAT_MIRRORING_RX_DROP_B] = "mirr_rx_dop_B", + [STAT_RAW_PKT_MIRR_BLOCK_PKT] = "mirr_block_pkt", + [STAT_RAW_PKT_MIRR_BLOCK_B] = "mirr_block_B", - // control packet - [STAT_CONTROL_RX_PKT] = "ctrl_rx_pkt", - [STAT_CONTROL_RX_B] = "ctrl_rx_B", + [STAT_RAW_PKT_MIRR_RX_DROP_PKT] = "mirr_rxdop_pkt", + [STAT_RAW_PKT_MIRR_RX_DROP_B] = "mirr_rxdop_B", - [STAT_CTRL_PKT_OPENING] = "ctrl_pkt_open", - [STAT_CTRL_PKT_ACTIVE] = "ctrl_pkt_avtive", - [STAT_CTRL_PKT_CLOSING] = "ctrl_pkt_close", - [STAT_CTRL_PKT_RESETALL] = "ctrl_pkt_reset", - [STAT_CTRL_PKT_ERROR] = "ctrl_pkt_error", + [STAT_RAW_PKT_MIRR_TX_PKT] = "mirro_tx_pkt", + [STAT_RAW_PKT_MIRR_TX_B] = "mirro_tx_B", - // current session number - [STAT_CURRENT_SESSION_NUMS] = "curr_sess_num", + [STAT_RAW_PKT_STEE_BYPASS_PKT] = "stee_bypass_pkt", + [STAT_RAW_PKT_STEE_BYPASS_B] = "stee_bypass_B", - // keepalive packet - [STAT_DOWNLINK_KEEPALIVE_RX_PKT] = "dlnk_kep_rx_pkt", - [STAT_DOWNLINK_KEEPALIVE_RX_B] = "dlnk_kep_rx_B", - [STAT_UPLINK_KEEPALIVE_RX_PKT] = "ulnk_kep_rx_pkt", - [STAT_UPLINK_KEEPALIVE_RX_B] = "ulnk_kep_rx_B", + [STAT_RAW_PKT_STEE_BLOCK_PKT] = "stee_block_pkt", + [STAT_RAW_PKT_STEE_BLOCK_B] = "stee_block_B", - // health check - [STAT_SF_ACTIVE_TIMES] = "sf_active", - [STAT_SF_INACTIVE_TIMES] = "sf_inactive", + [STAT_RAW_PKT_STEE_RX_PKT] = "stee_rx_pkt", + [STAT_RAW_PKT_STEE_RX_B] = "stee_rx_B", - // send log - [STAT_SEND_LOG] = "send_log", + [STAT_RAW_PKT_STEE_TX_PKT] = "stee_tx_pkt", + [STAT_RAW_PKT_STEE_TX_B] = "stee_tx_B", + + [STAT_RAW_PKT_MISS_SESS_PKT] = "miss_sess_pkt", + [STAT_RAW_PKT_MISS_SESS_B] = "miss_sess_B", + + [STAT_RAW_PKT_ERROR_BYPASS_PKT] = "err_bypass_pkt", + [STAT_RAW_PKT_ERROR_BYPASS_B] = "err_bypass_B", + + [STAT_RAW_PKT_ERROR_BLOCK_PKT] = "err_block_pkt", + [STAT_RAW_PKT_ERROR_BLOCK_B] = "err_block_B", + + [STAT_DEVICE_ENDPOINT_DROP_PKT] = "endp_drop_pkt", + [STAT_DEVICE_ENDPOINT_DROP_B] = "endp_drop_B", + + // ctrl_pkt_metrics + [STAT_CTRL_PKT_RX_PKT] = "ctrl_rx_pkt", + [STAT_CTRL_PKT_RX_B] = "ctrl_rx_B", + + [STAT_CTRL_PKT_TX_PKT] = "ctrl_tx_pkt", + [STAT_CTRL_PKT_TX_B] = "ctrl_tx_B", + + [STAT_CTRL_PKT_OPENING] = "ctrl_opening", + [STAT_CTRL_PKT_ACTIVE] = "ctrl_active", + [STAT_CTRL_PKT_CLOSING] = "ctrl_closing", + [STAT_CTRL_PKT_RESETALL] = "ctrl_resetall", + [STAT_CTRL_PKT_ERROR] = "ctrl_error", + + // sf_session_metrics + [STAT_SF_SESSION_NUM] = "session_num", + [STAT_SF_SESSION_LOG] = "session_logs", + + // sf_status_metrics + [STAT_SF_STATUS_ACTIVE] = "sf_active", + [STAT_SF_STATUS_INACTIVE] = "sf_inactive", [STAT_MAX] = NULL}; -static void global_metrics_parse_config(const char *profile, struct global_metrics_config *config) +static void global_metrics_parse_config(const char *profile, struct metrics_config *config) { MESA_load_profile_string_def(profile, "STAT", "output_file", config->output_file, sizeof(config->output_file), "log/sce.fs2"); MESA_load_profile_string_def(profile, "STAT", "statsd_server", config->statsd_server, sizeof(config->statsd_server), "127.0.0.1"); @@ -231,73 +267,90 @@ void global_metrics_destory(struct global_metrics *metrics) void global_metrics_dump(struct global_metrics *metrics) { - // dev endpoint - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_ENDPOINT_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->dev_endpoint_rx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_ENDPOINT_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->dev_endpoint_rx.n_bytes), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_ENDPOINT_TX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->dev_endpoint_tx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_ENDPOINT_TX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->dev_endpoint_tx.n_bytes), 0, __ATOMIC_RELAXED)); + // device_metrics + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_rx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_rx.n_bytes))); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_ENDPOINT_ERR_DROP_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->dev_endpoint_err_drop.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_ENDPOINT_ERR_DROP_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->dev_endpoint_err_drop.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_tx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_tx.n_bytes))); - // dev nf interface - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->raw_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->raw_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_rx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_rx.n_bytes))); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_TX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->raw_pkt_tx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_TX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->raw_pkt_tx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_tx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_tx.n_bytes))); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERR_BYPASS_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->raw_pkt_err_bypass.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERR_BYPASS_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->raw_pkt_err_bypass.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_DROP_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_drop.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_DROP_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_drop.n_bytes))); - // hit block policy - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_HIT_BLOCK_POLICY_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->hit_block_policy.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_HIT_BLOCK_POLICY_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->hit_block_policy.n_bytes), 0, __ATOMIC_RELAXED)); + // raw_pkt_metrics + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BYPASS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_bypass.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BYPASS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_bypass.n_bytes))); - // hit bypass policy - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_HIT_BYPASS_POLICY_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->hit_bypass_policy.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_HIT_BYPASS_POLICY_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->hit_bypass_policy.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BLOCK_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_block.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BLOCK_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_block.n_bytes))); - // steering - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_STEERING_TX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->steering_tx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_STEERING_TX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->steering_tx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_RX_DROP_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_rx_drop.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_RX_DROP_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_rx_drop.n_bytes))); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_STEERING_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->steering_rx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_STEERING_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->steering_rx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_tx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_tx.n_bytes))); - // mirroring - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_MIRRORING_TX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->mirroring_tx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_MIRRORING_TX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->mirroring_tx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BYPASS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_bypass.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BYPASS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_bypass.n_bytes))); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_MIRRORING_RX_DROP_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->mirroring_rx_drop.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_MIRRORING_RX_DROP_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->mirroring_rx_drop.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BLOCK_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_block.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BLOCK_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_block.n_bytes))); - // keepalive packet - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DOWNLINK_KEEPALIVE_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->downlink_keepalive_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DOWNLINK_KEEPALIVE_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->downlink_keepalive_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_UPLINK_KEEPALIVE_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->uplink_keepalive_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_UPLINK_KEEPALIVE_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->uplink_keepalive_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_rx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_rx.n_bytes))); - // control packet - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CONTROL_RX_PKT], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_pkts), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CONTROL_RX_B], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_rx.n_bytes), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_tx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_tx.n_bytes))); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_OPENING], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_opening_num), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_ACTIVE], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_active_num), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_CLOSING], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_closing_num), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_RESETALL], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_resetall_num), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_ERROR], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->ctrl_pkt_error_num), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MISS_SESS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.miss_sess.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MISS_SESS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.miss_sess.n_bytes))); - // current session number - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CURRENT_SESSION_NUMS], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->session_nums), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BYPASS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_bypass.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BYPASS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_bypass.n_bytes))); - // health check - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_ACTIVE_TIMES], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->sf_active_times), 0, __ATOMIC_RELAXED)); - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_INACTIVE_TIMES], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->sf_inactive_times), 0, __ATOMIC_RELAXED)); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BLOCK_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_block.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BLOCK_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_block.n_bytes))); - // send log - FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SEND_LOG], 0, FS_OP_SET, __atomic_fetch_add(&(metrics->send_log), 0, __ATOMIC_RELAXED)); + // ctrl_pkt_metrics + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.rx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.rx.n_bytes))); + + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.tx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.tx.n_bytes))); + + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_OPENING], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.opening))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_ACTIVE], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.active))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_CLOSING], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.closing))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_RESETALL], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.resetall))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_ERROR], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.error))); + + // keepalived_pkt_metrics + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_rx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_rx.n_bytes))); + + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_tx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_tx.n_bytes))); + + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_rx.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_rx.n_bytes))); + + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_TX_DROP_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_tx_drop.n_pkts))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_TX_DROP_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_tx_drop.n_bytes))); + + // sf_status_metrics + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_STATUS_ACTIVE], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_status.active))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_STATUS_INACTIVE], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_status.inactive))); + + // sf_session_metrics + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_SESSION_NUM], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_session.num))); + FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_SESSION_LOG], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_session.log))); FS_passive_output(metrics->fs_handle); } diff --git a/platform/src/main.cpp b/platform/src/main.cpp index 364955d..d6382d4 100644 --- a/platform/src/main.cpp +++ b/platform/src/main.cpp @@ -37,21 +37,6 @@ static void sig_handler(int signo) } } -static int thread_set_affinity(int core_id) -{ - int num_cores = sysconf(_SC_NPROCESSORS_ONLN); - if (core_id < 0 || core_id >= num_cores) - { - return EINVAL; - } - - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(core_id, &cpuset); - - return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); -} - static void *worker_thread_cycle(void *arg) { struct thread_ctx *thread_ctx = (struct thread_ctx *)arg; @@ -78,8 +63,8 @@ static void *worker_thread_cycle(void *arg) while (1) { - n_pkt_recv_from_nf = packet_io_polling_nf_interface(handle, thread_ctx->thread_index, thread_ctx); - n_pkt_recv_from_endp = packet_io_polling_endpoint(handle, thread_ctx->thread_index, thread_ctx); + n_pkt_recv_from_nf = packet_io_thread_polling_nf(handle, thread_ctx); + n_pkt_recv_from_endp = packet_io_thread_polling_endpoint(handle, thread_ctx); if (n_pkt_recv_from_nf == 0 && n_pkt_recv_from_endp == 0) { timeout_ms = sf_metrics_last_send_ts + sf_metrics_send_interval - timestamp_get_msec(ts); @@ -91,10 +76,10 @@ static void *worker_thread_cycle(void *arg) packet_io_thread_wait(handle, thread_ctx, timeout_ms); } - if (__atomic_fetch_add(&thread_ctx->session_table_need_reset, 0, __ATOMIC_RELAXED) > 0) + if (ATOMIC_READ(&thread_ctx->session_table_need_reset) > 0) { session_table_reset(thread_ctx->session_table); - __atomic_fetch_and(&thread_ctx->session_table_need_reset, 0, __ATOMIC_RELAXED); + ATOMIC_ZERO(&thread_ctx->session_table_need_reset); } if (timestamp_get_msec(ts) - sf_metrics_last_send_ts >= sf_metrics_send_interval) @@ -131,12 +116,12 @@ int main(int argc, char **argv) return 0; } } - fprintf(stderr, "TSG Service Chaining Engine, Version: %s\n", __sce_version); if (LOG_INIT("./conf/zlog.conf") == -1) { return -1; } + LOG_ERROR("%s: TSG Service Chaining Engine, Version: %s Start ...", LOG_TAG_SCE, __sce_version); if (signal(SIGHUP, sig_handler) == SIG_ERR) { diff --git a/platform/src/packet_io.cpp b/platform/src/packet_io.cpp index a4900ae..b584c07 100644 --- a/platform/src/packet_io.cpp +++ b/platform/src/packet_io.cpp @@ -15,24 +15,8 @@ #include "ctrl_packet.h" #include "global_metrics.h" -/* - * add: vxlan_hdr - * del: marsio_buff_ctrlzone_reset() - * +----+ NF2SF +----+ - * | |--------------------------->| | - * | | | | - * | |-------+ | |-------+ - * | NF | | NF2NF (undo) | SF | | SF2SF (del old vxlan_hdr; add new vxlan_hdr) - * | |<------+ | |<------+ - * | | | | - * | |<---------------------------| | - * | | SF2NF | | - * +---+ del: vxlan_hdr +----+ - * add: session_id + route_ctx + sid - */ - /****************************************************************************** - * Struct + * struct ******************************************************************************/ #define RX_BURST_MAX 128 @@ -44,7 +28,6 @@ struct config char app_symbol[256]; char dev_endpoint[256]; char dev_nf_interface[256]; - char dev_endpoint_src_ip[16]; char dev_endpoint_src_mac[32]; }; @@ -64,118 +47,977 @@ struct packet_io struct config config; }; -enum raw_pkt_action -{ - RAW_PKT_ERR_BYPASS, - RAW_PKT_HIT_BYPASS, - RAW_PKT_HIT_BLOCK, - RAW_PKT_HIT_STEERING, - RAW_PKT_HIT_MIRRORING, -}; - -enum inject_pkt_action -{ - INJT_PKT_ERR_DROP, - INJT_PKT_MIRR_RX_DROP, - INJT_PKT_HIT_BLOCK, - INJT_PKT_HIT_FWD2SF, // forward to service function - INJT_PKT_HIT_FWD2NF, // forward to network function -}; - -struct metadata -{ - uint64_t session_id; - - char *raw_data; - int raw_len; - - int dir_is_e2i; - int is_ctrl_pkt; - - uint16_t l7_offset; // only control packet set l7_offset - int traffic_is_decrypted; // only raw packet set traffic_is_decrypted - - struct sids sids; - struct route_ctx route_ctx; -}; - /****************************************************************************** - * API Declaration + * metadata ******************************************************************************/ -struct packet_io *packet_io_create(const char *profile, int thread_num, cpu_set_t *coremask); -void packet_io_destory(struct packet_io *handle); +// return 0 : success +// return -1 : error +static int mbuff_get_metadata(marsio_buff_t *rx_buff, struct metadata *meta) +{ + memset(meta, 0, sizeof(struct metadata)); -int packet_io_polling_nf_interface(struct packet_io *handle, int thread_seq, void *ctx); -int packet_io_polling_endpoint(struct packet_io *handle, int thread_seq, void *ctx); + meta->raw_len = marsio_buff_datalen(rx_buff); + meta->raw_data = marsio_buff_mtod(rx_buff); + if (meta->raw_data == NULL || meta->raw_len == 0) + { + LOG_ERROR("%s: unable to get raw_data from metadata", LOG_TAG_PKTIO); + return -1; + } + + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) <= 0) + { + LOG_ERROR("%s: unable to get session_id from metadata", LOG_TAG_PKTIO); + return -1; + } + + // 1: E2I + // 0: I2E + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_DIR, &(meta->is_e2i_dir), sizeof(meta->is_e2i_dir)) <= 0) + { + LOG_ERROR("%s: unable to get buff_dir from metadata", LOG_TAG_PKTIO); + return -1; + } + + if (marsio_buff_is_ctrlbuf(rx_buff)) + { + meta->is_ctrl_pkt = 1; + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7offset), sizeof(meta->l7offset)) <= 0) + { + LOG_ERROR("%s: unable to get l7offset from metadata", LOG_TAG_PKTIO); + return -1; + } + } + else + { + meta->is_ctrl_pkt = 0; +#if 0 + if (marsio_buff_get_metadata(rx_buff, MR_IS_DECRYPTED, &(meta->is_decrypted), sizeof(meta->is_decrypted)) <= 0) + { + LOG_ERROR("%s: unable to get is_decrypted from metadata", LOG_TAG_PKTIO); + return -1; + } +#endif + } + + meta->sids.num = marsio_buff_get_sid_list(rx_buff, meta->sids.elems, sizeof(meta->sids.elems) / sizeof(meta->sids.elems[0])); + if (meta->sids.num < 0) + { + LOG_ERROR("%s: unable to get sid_list from metadata", LOG_TAG_PKTIO); + return -1; + } + + meta->route_ctx.len = marsio_buff_get_metadata(rx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, sizeof(meta->route_ctx.data)); + if (meta->route_ctx.len <= 0) + { + LOG_ERROR("%s: unable to get route_ctx from metadata", LOG_TAG_PKTIO); + return -1; + } + + return 0; +} // return 0 : success // return -1 : error -static int packet_io_config(const char *profile, struct config *config); +static int mbuff_set_metadata(marsio_buff_t *tx_buff, struct metadata *meta) +{ + if (meta->session_id) + { + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) != 0) + { + LOG_ERROR("%s: unable to set session_id for metadata", LOG_TAG_PKTIO); + return -1; + } + } -// return 0 : success -// return -1 : error -static int packet_io_get_metadata(marsio_buff_t *tx_buff, struct metadata *meta); -// return 0 : success -// return -1 : error -static int packet_io_set_metadata(marsio_buff_t *tx_buff, struct metadata *meta); -static void packet_io_dump_metadata(marsio_buff_t *tx_buff, struct metadata *meta); + // need't set MR_BUFF_DIR, set MR_BUFF_ROUTE_CTX instead -// return 0 : success -// return -1 : error -static int handle_control_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx); -// return : RAW_PKT_ERR_BYPASS -// return : RAW_PKT_HIT_BYPASS -// return : RAW_PKT_HIT_BLOCK -// reutrn : RAW_PKT_HIT_STEERING -// return : RAW_PKT_HIT_MIRRORING -static enum raw_pkt_action handle_raw_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx, int *action_bytes); -// return : INJT_PKT_ERR_DROP -// return : INJT_PKT_MIRR_RX_DROP -// return : INJT_PKT_HIT_BLOCK -// return : INJT_PKT_HIT_FWD2SF -// return : INJT_PKT_HIT_FWD2NF -static enum inject_pkt_action handle_inject_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx, int *action_bytes); + if (meta->is_ctrl_pkt) + { + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7offset), sizeof(meta->l7offset)) != 0) + { + LOG_ERROR("%s: unable to set l7offset for metadata", LOG_TAG_PKTIO); + return -1; + } + } + else + { + // TODO +#if 0 + if (marsio_buff_set_metadata(tx_buff, MR_IS_DECRYPTED, &(meta->is_decrypted), sizeof(meta->is_decrypted)) != 0) + { + LOG_ERROR("%s: unable to set is_decrypted for metadata", LOG_TAG_PKTIO); + return -1; + } +#endif + } -// rx_buff : not include g_vxlan header -// return + : send n bytes -// return -1 : error -static int forward_packet_to_sf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, int thread_seq, void *ctx); -// rx_buff : not include g_vxlan header -// return + : send n bytes -// return -1 : error -static int mirror_packet_to_sf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, int thread_seq, void *ctx); -// rx_buff : not include g_vxlan header -// return + : send n bytes -// return -1 : error -static int forward_packet_to_nf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, int thread_seq, void *ct); + if (meta->sids.num > 0) + { + if (marsio_buff_set_sid_list(tx_buff, meta->sids.elems, meta->sids.num) != 0) + { + LOG_ERROR("%s: unable to set sid_list for metadata", LOG_TAG_PKTIO); + return -1; + } + } -// return 0 : success -// return -1 : error -static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); -// return 0 : success -// return -1 : error -static int handle_session_closing(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); -// return 0 : success -// return -1 : error -static int handle_session_active(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); -// return 0 : success -// return -1 : error -static int handle_session_resetall(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx); + if (meta->route_ctx.len > 0) + { + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, meta->route_ctx.len) != 0) + { + LOG_ERROR("%s: unable to set route_ctx for metadata", LOG_TAG_PKTIO); + return -1; + } + } -static void session_value_free_cb(void *ctx); + return 0; +} // return 0 : not keepalive packet // return 1 : is keepalive packet -static int is_downstream_keepalive_packet(marsio_buff_t *rx_buff); +static int is_downlink_keepalive_packet(marsio_buff_t *rx_buff) +{ + int raw_len = marsio_buff_datalen(rx_buff); + char *raw_data = marsio_buff_mtod(rx_buff); + if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr))) + { + return 0; + } + + struct ethhdr *eth_hdr = (struct ethhdr *)raw_data; + if (eth_hdr->h_proto == 0xAAAA) + { + return 1; + } + else + { + return 0; + } +} + // return 0 : not keepalive packet // return 1 : is keepalive packet -static int is_upstream_keepalive_packet(marsio_buff_t *rx_buff); +static int is_uplink_keepalive_packet(marsio_buff_t *rx_buff) +{ + int raw_len = marsio_buff_datalen(rx_buff); + char *raw_data = marsio_buff_mtod(rx_buff); + if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udp_hdr))) + { + return 0; + } + + struct ethhdr *eth_hdr = (struct ethhdr *)raw_data; + if (eth_hdr->h_proto != htons(ETH_P_IP)) + { + return 0; + } + + struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr)); + if (ip_hdr->ip_p != IPPROTO_UDP) + { + return 0; + } + + struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ip)); + if (udp_hdr->uh_dport != htons(3784)) + { + return 0; + } + + return 1; +} /****************************************************************************** - * API Definition + * search session ctx ******************************************************************************/ +// return !NULL +// return NULL +static struct session_ctx *raw_packet_search_session(struct session_table *table, const char *raw_data, int raw_len, uint64_t session_id) +{ + struct addr_tuple4 inner_addr; + struct addr_tuple4 reverse_addr; + struct raw_pkt_parser raw_parser; + + memset(&inner_addr, 0, sizeof(struct addr_tuple4)); + memset(&reverse_addr, 0, sizeof(struct addr_tuple4)); + + raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); + raw_packet_parser_parse(&raw_parser, (const void *)raw_data, raw_len); + + raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); + addr_tuple4_reverse(&inner_addr, &reverse_addr); + + struct session_node *node = session_table_search_by_id(table, session_id); + if (node == NULL) + { + return NULL; + } + + struct session_ctx *session_ctx = (struct session_ctx *)node->value; + if (memcmp(&session_ctx->inner_tuple4, &inner_addr, sizeof(struct addr_tuple4)) != 0 && memcmp(&session_ctx->inner_tuple4, &reverse_addr, sizeof(struct addr_tuple4)) != 0) + { + char *addr_str = addr_tuple4_to_str(&inner_addr); + LOG_ERROR("%s: unexpected raw packet, session %lu expected address tuple4 is %s, but current packet's address tuple4 is %s, bypass !!!", LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr, addr_str); + free(addr_str); + return NULL; + } + + return session_ctx; +} + +// return !NULL +// return NULL +static struct session_ctx *inject_packet_search_session(struct session_table *table, const char *raw_data, int raw_len) +{ + struct addr_tuple4 inner_addr; + struct raw_pkt_parser raw_parser; + + memset(&inner_addr, 0, sizeof(struct addr_tuple4)); + + raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); + raw_packet_parser_parse(&raw_parser, (const void *)raw_data, raw_len); + + raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); + + struct session_node *node = session_table_search_by_addr(table, &inner_addr); + if (node == NULL) + { + char *addr_str = addr_tuple4_to_str(&inner_addr); + LOG_ERROR("%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_str); + free(addr_str); + return NULL; + } + + return (struct session_ctx *)node->value; +} + +/****************************************************************************** + * action bypass/block/forward + ******************************************************************************/ + +static void vxlan_encapsulate(char *buffer, const char *src_mac_str, const char *dst_mac_str, const char *src_ip_str, const char *dst_ip_str, int payload_len, int is_e2i, int is_decrypted, int sf_index) +{ + struct ethhdr *eth_hdr = (struct ethhdr *)buffer; + struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr)); + struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ip)); + struct g_vxlan *g_vxlan_hdr = (struct g_vxlan *)((char *)udp_hdr + sizeof(struct udp_hdr)); + + memset(g_vxlan_hdr, 0, sizeof(struct g_vxlan)); + g_vxlan_set_packet_dir(g_vxlan_hdr, is_e2i); + g_vxlan_set_sf_index(g_vxlan_hdr, sf_index); + g_vxlan_set_traffic_type(g_vxlan_hdr, is_decrypted); + + build_ether_header(eth_hdr, ETH_P_IP, src_mac_str, dst_mac_str); + build_ip_header(ip_hdr, IPPROTO_UDP, src_ip_str, dst_ip_str, sizeof(struct udp_hdr) + sizeof(struct g_vxlan) + payload_len); + build_udp_header((const char *)&ip_hdr->ip_src, 8, udp_hdr, rand() % (65535 - 49152) + 49152, 4789, sizeof(struct g_vxlan) + payload_len); +} + +static int send_packet_to_sf(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct packet_io *packet_io = thread_ctx->ref_io; + int thread_index = thread_ctx->thread_index; + + const char *src_mac_str = packet_io->config.dev_endpoint_src_mac; + const char *dst_mac_str = sf->sf_dst_mac; + const char *src_ip_str = packet_io->config.dev_endpoint_src_ip; + const char *dst_ip_str = sf->sf_dst_ip; + int payload_len = meta->raw_len; + int is_e2i = meta->is_e2i_dir; + int is_decrypted = meta->is_decrypted; + int sf_index = sf->sf_index; + int prepend_len = 0; + char *buffer = NULL; + + marsio_buff_ctrlzone_reset(rx_buff); + switch (sf->sf_connectivity.method) + { + case PACKAGE_METHOD_VXLAN_G: + prepend_len = sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udp_hdr) + sizeof(struct g_vxlan); + buffer = marsio_buff_prepend(rx_buff, prepend_len); + vxlan_encapsulate(buffer, src_mac_str, dst_mac_str, src_ip_str, dst_ip_str, payload_len, is_e2i, is_decrypted, sf_index); + break; + case PACKAGE_METHOD_LAYER2_SWITCH: + // TODO + break; + case PACKAGE_METHOD_LAYER3_SWITCH: + // TODO + break; + default: + break; + } + + int nsend = marsio_buff_datalen(rx_buff); + marsio_send_burst(packet_io->dev_endpoint.mr_path, thread_index, &rx_buff, 1); + return nsend; +} + +static int action_nf_inject(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx); + +static void action_err_bypass(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + + int nsend = action_nf_inject(rx_buff, meta, sf, thread_ctx); + if (nsend > 0) + { + throughput_metrics_inc(&(g_metrics->raw_pkt.error_bypass), 1, nsend); + } +} + +static void action_err_block(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct packet_io *packet_io = thread_ctx->ref_io; + int thread_index = thread_ctx->thread_index; + + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&(g_metrics->raw_pkt.error_block), 1, raw_len); + marsio_buff_free(packet_io->instance, &rx_buff, 1, 0, thread_index); +} + +// return nsend +static int action_nf_inject(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct packet_io *packet_io = thread_ctx->ref_io; + int thread_index = thread_ctx->thread_index; + + marsio_buff_ctrlzone_reset(rx_buff); + if (mbuff_set_metadata(rx_buff, meta) != 0) + { + action_err_block(rx_buff, meta, sf, thread_ctx); + return 0; + } + + int raw_len = marsio_buff_datalen(rx_buff); + marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread_index, &rx_buff, 1); + throughput_metrics_inc(&(g_metrics->device.nf_tx), 1, raw_len); + return raw_len; +} + +static void action_mirr_bypass(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&(g_metrics->raw_pkt.mirr_bypass), 1, raw_len); +} + +static void action_mirr_block(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&(g_metrics->raw_pkt.mirr_block), 1, raw_len); +} + +static void action_mirr_forward(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct packet_io *packet_io = thread_ctx->ref_io; + int thread_index = thread_ctx->thread_index; + + int raw_len = marsio_buff_datalen(rx_buff); + char *raw_data = marsio_buff_mtod(rx_buff); + + marsio_buff_t *new_buff = NULL; + if (marsio_buff_malloc_global(packet_io->instance, &new_buff, 1, MARSIO_SOCKET_ID_ANY, MARSIO_LCORE_ID_ANY) < 0) + { + LOG_ERROR("%s: unable to malloc buff on marsio instance, thread_index: %d", LOG_TAG_PKTIO, thread_index); + return; + } + + char *copy_ptr = marsio_buff_append(new_buff, raw_len); + memcpy(copy_ptr, raw_data, raw_len); + + int nsend = send_packet_to_sf(new_buff, meta, sf, thread_ctx); + throughput_metrics_inc(&(g_metrics->device.endpoint_tx), 1, nsend); + throughput_metrics_inc(&(g_metrics->raw_pkt.mirr_tx), 1, raw_len); + throughput_metrics_inc(&sf->tx, 1, nsend); + sf_metrics_inc(thread_ctx->sf_metrics, sf->policy_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend); +} + +static void action_stee_bypass(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&(g_metrics->raw_pkt.stee_bypass), 1, raw_len); +} + +static void action_stee_block(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct packet_io *packet_io = thread_ctx->ref_io; + int thread_index = thread_ctx->thread_index; + + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&(g_metrics->raw_pkt.stee_block), 1, raw_len); + marsio_buff_free(packet_io->instance, &rx_buff, 1, 0, thread_index); +} + +static void action_stee_forward(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + + int raw_len = marsio_buff_datalen(rx_buff); + int nsend = send_packet_to_sf(rx_buff, meta, sf, thread_ctx); + throughput_metrics_inc(&(g_metrics->device.endpoint_tx), 1, nsend); + throughput_metrics_inc(&(g_metrics->raw_pkt.stee_tx), 1, raw_len); + throughput_metrics_inc(&sf->tx, 1, nsend); + sf_metrics_inc(thread_ctx->sf_metrics, sf->policy_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend); +} + +static void action_sf_chaining(struct thread_ctx *thread_ctx, struct session_ctx *session_ctx, struct selected_chaining *chaining, marsio_buff_t *rx_buff, struct metadata *meta, int next_sf_index) +{ + int sf_index; + for (sf_index = next_sf_index; sf_index < chaining->chaining_used; sf_index++) + { + struct selected_sf *sf = &(chaining->chaining[sf_index]); + LOG_INFO("%s: session: %lu %s execute chaining [%d/%d] policy_id: %d, sff_profile_id: %d, sf_profile_id: %d, sf_need_skip: %d, sf_action_reason: %s, is_e2i: %d, is_decrypted: %d", + LOG_TAG_POLICY, session_ctx->session_id, session_ctx->session_addr, sf_index, chaining->chaining_used, + sf->policy_id, sf->sff_profile_id, sf->sf_profile_id, sf->sf_need_skip, action_reason_to_string(sf->sf_action_reason), + meta->is_e2i_dir, meta->is_decrypted); + + if (sf->sf_need_skip) + { + continue; + } + + switch (sf->sf_action) + { + case SESSION_ACTION_BYPASS: + if (sf->sff_forward_type == FORWARD_TYPE_STEERING) + { + action_stee_bypass(rx_buff, meta, sf, thread_ctx); + continue; + } + else + { + action_mirr_bypass(rx_buff, meta, sf, thread_ctx); + continue; + } + case SESSION_ACTION_BLOCK: + if (sf->sff_forward_type == FORWARD_TYPE_STEERING) + { + action_stee_block(rx_buff, meta, sf, thread_ctx); + return; + } + else + { + action_mirr_block(rx_buff, meta, sf, thread_ctx); + return; + } + + case SESSION_ACTION_FORWARD: + if (sf->sf_connectivity.method != PACKAGE_METHOD_VXLAN_G) + { + LOG_ERROR("%s: processing packets, session %lu %s requires encapsulation format not supported, bypass !!!", + LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr); + action_err_bypass(rx_buff, meta, sf, thread_ctx); + return; + } + + if (sf->sff_forward_type == FORWARD_TYPE_STEERING) + { + action_stee_forward(rx_buff, meta, sf, thread_ctx); + return; + } + else + { + action_mirr_forward(rx_buff, meta, sf, thread_ctx); + continue; + } + } + } + + if (sf_index == chaining->chaining_used) + { + action_nf_inject(rx_buff, meta, NULL, thread_ctx); + } +} + +/****************************************************************************** + * handle session status + ******************************************************************************/ + +static int send_event_log(struct session_ctx *session_ctx, struct selected_chaining *chaining, struct thread_ctx *thread_ctx) +{ + struct sce_ctx *sce_ctx = thread_ctx->ref_sce_ctx; + struct packet_io *packet_io = thread_ctx->ref_io; + int thread_index = thread_ctx->thread_index; + + char buffer[32] = {0}; + sprintf(buffer, "%lu", session_ctx->session_id); + cJSON *root = cJSON_CreateObject(); + cJSON_AddStringToObject(root, "tsync", "1.0"); + cJSON_AddStringToObject(root, "session_id", buffer); + cJSON_AddStringToObject(root, "state", "closing"); + cJSON_AddStringToObject(root, "method", "log_update"); + cJSON *sf_profile_ids = cJSON_CreateArray(); + for (int i = 0; i < chaining->chaining_used; i++) + { + struct selected_sf *sf = &(chaining->chaining[i]); + if (sf->sf_need_skip == 0 && sf->sf_action == SESSION_ACTION_FORWARD) + { + cJSON *id = cJSON_CreateNumber(sf->sf_profile_id); + cJSON_AddItemToArray(sf_profile_ids, id); + } + } + cJSON *params = cJSON_CreateObject(); + cJSON_AddItemToObject(params, "sf_profile_ids", sf_profile_ids); + cJSON_AddItemToObject(root, "params", params); + char *json_str = cJSON_PrintUnformatted(root); + + LOG_INFO("%s: session %lu %s event log: %s", LOG_TAG_METRICS, session_ctx->session_id, session_ctx->session_addr, json_str); + + marsio_buff_t *tx_buffs[1]; + char *raw_packet_header_data = session_ctx->ctrl_meta->raw_data; + int raw_packet_header_len = session_ctx->ctrl_meta->l7offset; + marsio_buff_malloc_global(packet_io->instance, tx_buffs, 1, 0, thread_index); + char *dst = marsio_buff_append(tx_buffs[0], raw_packet_header_len + strlen(json_str)); + memcpy(dst, raw_packet_header_data, raw_packet_header_len); + memcpy(dst + raw_packet_header_len, json_str, strlen(json_str)); + + struct metadata meta = {0}; + meta.session_id = session_ctx->session_id; + meta.l7offset = raw_packet_header_len; + meta.is_ctrl_pkt = 1; + meta.sids.num = 1; + meta.sids.elems[0] = sce_ctx->firewall_sids; + route_ctx_copy(&meta.route_ctx, &session_ctx->ctrl_meta->route_ctx); + mbuff_set_metadata(tx_buffs[0], &meta); + int nsend = marsio_buff_datalen(tx_buffs[0]); + marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread_index, tx_buffs, 1); + free(json_str); + cJSON_Delete(root); + + return nsend; +} + +static void dump_event_log(struct session_ctx *session_ctx, struct selected_chaining *chaining, const char *tag) +{ + if (chaining == NULL) + { + return; + } + + for (int i = 0; i < chaining->chaining_used; i++) + { + struct selected_sf *sf = &(chaining->chaining[i]); + LOG_INFO("%s: session %lu %s %s metrics log: policy %d sff_profile_id %d sf_profile_id %d sf_need_skip %d sf_action_reason %s rx_pkts %lu rx_bytes %lu tx_pkts %lu tx_bytes %lu", + LOG_TAG_METRICS, session_ctx->session_id, session_ctx->session_addr, tag, sf->policy_id, sf->sff_profile_id, sf->sf_profile_id, sf->sf_need_skip, action_reason_to_string(sf->sf_action_reason), sf->rx.n_pkts, sf->rx.n_bytes, sf->tx.n_pkts, sf->tx.n_bytes); + } +} + +static void session_value_free_cb(void *ctx) +{ + struct session_ctx *s_ctx = (struct session_ctx *)ctx; + session_ctx_free(s_ctx); +} + +static void handle_policy_mutil_hits(struct policy_enforcer *enforcer, struct session_ctx *session_ctx, struct ctrl_pkt_parser *ctrl_parser, raw_pkt_parser *raw_parser, int is_e2i_dir) +{ + for (int i = 0; i < ctrl_parser->policy_id_num; i++) + { + int policy_id = ctrl_parser->policy_ids[i]; + if (fixed_num_array_exist_elem(&session_ctx->policy_ids, policy_id)) + { + continue; + } + else + { + policy_enforce_select_chainings(enforcer, &session_ctx->chainings, session_ctx, raw_parser, policy_id, is_e2i_dir); + + selected_chaining_bref(session_ctx->chainings.chaining_raw); + selected_chaining_bref(session_ctx->chainings.chaining_decrypted); + + fixed_num_array_add_elem(&session_ctx->policy_ids, policy_id); + } + } +} + +static void handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser *ctrl_parser, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct policy_enforcer *enforcer = thread_ctx->ref_enforcer; + struct session_table *session_table = thread_ctx->session_table; + int chaining_size = policy_enforce_chaining_size(enforcer); + +#if 0 + if (session_table_search_by_id(session_table, meta->session_id)) + { + return ; + } +#endif + + struct raw_pkt_parser raw_parser; + struct addr_tuple4 inner_tuple4; + raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); + const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); + raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_tuple4); + uint16_t real_offset = (char *)payload - meta->raw_data; + if (real_offset != meta->l7offset) + { + char *addr_str = addr_tuple4_to_str(&inner_tuple4); + LOG_ERROR("%s: incorrect dataoffset %d in the control zone of session %lu %s, the expect value is %d", LOG_TAG_PKTIO, meta->l7offset, meta->session_id, addr_str, real_offset); + free(addr_str); + } + + struct session_ctx *session_ctx = session_ctx_new(); + session_ctx->session_id = meta->session_id; + session_ctx->session_addr = addr_tuple4_to_str(&inner_tuple4); + addr_tuple4_copy(&session_ctx->inner_tuple4, &inner_tuple4); + metadata_deep_copy(session_ctx->ctrl_meta, meta); + session_ctx->chainings.chaining_raw = selected_chaining_create(chaining_size, session_ctx->session_id, session_ctx->session_addr); + session_ctx->chainings.chaining_decrypted = selected_chaining_create(chaining_size, session_ctx->session_id, session_ctx->session_addr); + session_ctx->ref_thread_ctx = thread_ctx; + + LOG_INFO("%s: session %lu %s active first", LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr); + handle_policy_mutil_hits(enforcer, session_ctx, ctrl_parser, &raw_parser, meta->is_e2i_dir); + + session_table_insert(session_table, session_ctx->session_id, &session_ctx->inner_tuple4, session_ctx, session_value_free_cb); + ATOMIC_INC(&(g_metrics->sf_session.num)); +} + +static void handle_session_closing(struct metadata *meta, struct ctrl_pkt_parser *ctrl_parser, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct session_table *session_table = thread_ctx->session_table; + struct sce_ctx *sce_ctx = thread_ctx->ref_sce_ctx; + int nsend = 0; + + struct session_node *node = session_table_search_by_id(session_table, meta->session_id); + if (node) + { + struct session_ctx *s_ctx = (struct session_ctx *)node->value; + LOG_INFO("%s: session %lu %s closing", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->session_addr); + + struct selected_chaining *chaining_raw = s_ctx->chainings.chaining_raw; + dump_event_log(s_ctx, chaining_raw, "raw_traffic"); + if (chaining_raw->chaining_used && sce_ctx->enable_send_log) + { + nsend = send_event_log(s_ctx, chaining_raw, thread_ctx); + ATOMIC_INC(&(g_metrics->sf_session.log)); + throughput_metrics_inc(&(g_metrics->ctrl_pkt.tx), 1, nsend); + throughput_metrics_inc(&(g_metrics->device.nf_tx), 1, nsend); + } + + struct selected_chaining *chaining_decrypted = s_ctx->chainings.chaining_decrypted; + dump_event_log(s_ctx, chaining_decrypted, "decrypted_traffic"); + if (chaining_decrypted->chaining_used && sce_ctx->enable_send_log) + { + nsend = send_event_log(s_ctx, chaining_decrypted, thread_ctx); + ATOMIC_INC(&(g_metrics->sf_session.log)); + throughput_metrics_inc(&(g_metrics->ctrl_pkt.tx), 1, nsend); + throughput_metrics_inc(&(g_metrics->device.nf_tx), 1, nsend); + } + + session_table_delete_by_id(session_table, meta->session_id); + ATOMIC_DEC(&(g_metrics->sf_session.num)); + } +} + +static void handle_session_active(struct metadata *meta, struct ctrl_pkt_parser *ctrl_parser, struct thread_ctx *thread_ctx) +{ + struct session_table *session_table = thread_ctx->session_table; + struct policy_enforcer *enforcer = thread_ctx->ref_enforcer; + + struct session_node *node = session_table_search_by_id(session_table, meta->session_id); + if (node) + { + struct session_ctx *session_ctx = (struct session_ctx *)node->value; + + struct raw_pkt_parser raw_parser; + raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); + const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); + uint16_t real_offset = (char *)payload - meta->raw_data; + if (real_offset != meta->l7offset) + { + LOG_ERROR("%s: incorrect dataoffset %d in the control zone of session %lu %s, the expect value is %d", LOG_TAG_PKTIO, meta->l7offset, meta->session_id, session_ctx->session_addr, real_offset); + } + + LOG_INFO("%s: session %lu %s active again", LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr); + handle_policy_mutil_hits(enforcer, session_ctx, ctrl_parser, &raw_parser, meta->is_e2i_dir); + } + else + { + handle_session_opening(meta, ctrl_parser, thread_ctx); + } +} + +static void handle_session_resetall(struct metadata *meta, struct ctrl_pkt_parser *ctrl_parser, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct sce_ctx *sce_ctx = thread_ctx->ref_sce_ctx; + + LOG_ERROR("%s: session %lu resetall: notification clears all session tables !!!", LOG_TAG_PKTIO, meta->session_id); + ATOMIC_ZERO(&(g_metrics->sf_session.num)); + for (int i = 0; i < sce_ctx->nr_worker_threads; i++) + { + struct thread_ctx *temp_ctx = &sce_ctx->work_threads[i]; + ATOMIC_INC(&temp_ctx->session_table_need_reset); + } +} + +/****************************************************************************** + * handle control/raw/inject packet + ******************************************************************************/ + +static void handle_control_packet(marsio_buff_t *rx_buff, struct thread_ctx *thread_ctx) +{ + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + struct metadata meta; + struct ctrl_pkt_parser ctrl_parser; + + if (mbuff_get_metadata(rx_buff, &meta) == -1) + { + LOG_ERROR("%s: unexpected control packet, unable to get metadata", LOG_TAG_PKTIO); + goto error_ctrl_pkt; + } + + ctrl_packet_parser_init(&ctrl_parser); + if (ctrl_packet_parser_parse(&ctrl_parser, meta.raw_data + meta.l7offset, meta.raw_len - meta.l7offset) == -1) + { + LOG_ERROR("%s: unexpected control packet, unable to parse data", LOG_TAG_PKTIO); + goto error_ctrl_pkt; + } + + if (ctrl_parser.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_parser.session_id); + goto error_ctrl_pkt; + } + + switch (ctrl_parser.state) + { + case SESSION_STATE_OPENING: + ATOMIC_INC(&(g_metrics->ctrl_pkt.opening)); + // when session opening, firewall not send policy id + // return handle_session_opening(&meta, &ctrl_parser, ctx); + break; + case SESSION_STATE_CLOSING: + ATOMIC_INC(&(g_metrics->ctrl_pkt.closing)); + handle_session_closing(&meta, &ctrl_parser, thread_ctx); + break; + case SESSION_STATE_ACTIVE: + ATOMIC_INC(&(g_metrics->ctrl_pkt.active)); + handle_session_active(&meta, &ctrl_parser, thread_ctx); + break; + case SESSION_STATE_RESETALL: + ATOMIC_INC(&(g_metrics->ctrl_pkt.resetall)); + handle_session_resetall(&meta, &ctrl_parser, thread_ctx); + break; + default: + goto error_ctrl_pkt; + } + return; + +error_ctrl_pkt: + ATOMIC_INC(&(g_metrics->ctrl_pkt.error)); + return; +} + +static void handle_raw_packet(marsio_buff_t *rx_buff, struct thread_ctx *thread_ctx) +{ + struct session_table *session_table = thread_ctx->session_table; + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + + struct metadata meta; + struct session_ctx *session_ctx = NULL; + struct selected_chaining *chaining = NULL; + + if (mbuff_get_metadata(rx_buff, &meta) == -1) + { + LOG_ERROR("%s: unexpected raw packet, unable to get metadata, bypass !!!", LOG_TAG_PKTIO); + goto error_bypass; + } + + session_ctx = raw_packet_search_session(session_table, meta.raw_data, meta.raw_len, meta.session_id); + if (session_ctx == NULL) + { + throughput_metrics_inc(&(g_metrics->raw_pkt.miss_sess), 1, meta.raw_len); + goto error_bypass; + } + + if (meta.is_e2i_dir) + { + if (metadata_is_empty(session_ctx->raw_meta_e2i)) + { + metadata_deep_copy(session_ctx->raw_meta_e2i, &meta); + } + } + else + { + if (metadata_is_empty(session_ctx->raw_meta_i2e)) + { + metadata_deep_copy(session_ctx->raw_meta_i2e, &meta); + } + } + + if (meta.is_decrypted == 1) + { + chaining = session_ctx->chainings.chaining_decrypted; + } + else + { + chaining = session_ctx->chainings.chaining_raw; + } + if (chaining == NULL) + { + LOG_ERROR("%s: unexpected raw packet, session %lu %s misses policy, bypass !!!", LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr); + goto error_bypass; + } + + action_sf_chaining(thread_ctx, session_ctx, chaining, rx_buff, &meta, 0); + return; + +error_bypass: + action_err_bypass(rx_buff, &meta, NULL, thread_ctx); +} + +static void handle_inject_packet(marsio_buff_t *rx_buff, struct thread_ctx *thread_ctx) +{ + struct session_table *session_table = thread_ctx->session_table; + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + + struct metadata meta; + struct g_vxlan *g_vxlan_hdr = NULL; + struct session_ctx *session_ctx = NULL; + struct selected_chaining *chaining = NULL; + + int sf_index = 0; + int raw_len = marsio_buff_datalen(rx_buff); + char *raw_data = marsio_buff_mtod(rx_buff); + if (g_vxlan_decode(&g_vxlan_hdr, raw_data, raw_len) == -1) + { + goto error_block; + } + + memset(&meta, 0, sizeof(struct metadata)); + meta.raw_data = (char *)g_vxlan_hdr + sizeof(struct g_vxlan); + meta.raw_len = raw_len - sizeof(struct ethhdr) - sizeof(struct ip) - sizeof(struct udp_hdr) - sizeof(struct g_vxlan); + meta.l7offset = 0; + meta.is_e2i_dir = g_vxlan_get_packet_dir(g_vxlan_hdr); + meta.is_ctrl_pkt = 0; + meta.is_decrypted = g_vxlan_get_traffic_type(g_vxlan_hdr); + sf_index = g_vxlan_get_sf_index(g_vxlan_hdr); + + session_ctx = inject_packet_search_session(session_table, meta.raw_data, meta.raw_len); + if (session_ctx == NULL) + { + goto error_block; + } + + meta.session_id = session_ctx->session_id; + if (meta.is_e2i_dir) + { + sids_copy(&meta.sids, &session_ctx->raw_meta_e2i->sids); + route_ctx_copy(&meta.route_ctx, &session_ctx->raw_meta_e2i->route_ctx); + } + else + { + sids_copy(&meta.sids, &session_ctx->raw_meta_i2e->sids); + route_ctx_copy(&meta.route_ctx, &session_ctx->raw_meta_i2e->route_ctx); + } + + if (meta.is_decrypted == 1) + { + chaining = session_ctx->chainings.chaining_decrypted; + } + else + { + chaining = session_ctx->chainings.chaining_raw; + } + + if (chaining == NULL || sf_index < 0 || sf_index >= chaining->chaining_used) + { + LOG_ERROR("%s: unexpected inject packet, session %lu %s misses chaining index, drop !!!", + LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr); + goto error_block; + } + + if (chaining->chaining[sf_index].sff_forward_type == FORWARD_TYPE_MIRRORING) + { + LOG_DEBUG("%s: unexpected inject packet, session %lu %s with sf_profile_id %d executes mirror and does not require reflow, drop !!!", + LOG_TAG_PKTIO, session_ctx->session_id, session_ctx->session_addr, chaining->chaining[sf_index].sf_profile_id); + throughput_metrics_inc(&(g_metrics->raw_pkt.mirr_rx_drop), 1, meta.raw_len); + goto error_block; + } + else + { + struct selected_sf *sf = &(chaining->chaining[sf_index]); + throughput_metrics_inc(&sf->rx, 1, raw_len); + throughput_metrics_inc(&(g_metrics->raw_pkt.stee_rx), 1, meta.raw_len); + sf_metrics_inc(thread_ctx->sf_metrics, sf->policy_id, sf->sff_profile_id, sf->sf_profile_id, 1, raw_len, 0, 0); + } + + marsio_buff_adj(rx_buff, raw_len - meta.raw_len); + action_sf_chaining(thread_ctx, session_ctx, chaining, rx_buff, &meta, sf_index + 1); + return; + +error_block: + throughput_metrics_inc(&(g_metrics->device.endpoint_drop), 1, raw_len); + marsio_buff_adj(rx_buff, raw_len - meta.raw_len); + action_err_block(rx_buff, &meta, NULL, thread_ctx); +} + +/****************************************************************************** + * packet io + ******************************************************************************/ + +// return 0 : success +// return -1 : error +static int packet_io_config(const char *profile, struct config *config) +{ + MESA_load_profile_int_def(profile, "PACKET_IO", "bypass_all_traffic", (int *)&(config->bypass_all_traffic), 0); + MESA_load_profile_int_def(profile, "PACKET_IO", "rx_burst_max", (int *)&(config->rx_burst_max), 1); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "app_symbol", config->app_symbol, sizeof(config->app_symbol)); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_endpoint", config->dev_endpoint, sizeof(config->dev_endpoint)); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_nf_interface", config->dev_nf_interface, sizeof(config->dev_nf_interface)); + + MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_endpoint_src_ip", config->dev_endpoint_src_ip, sizeof(config->dev_endpoint_src_ip)); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_endpoint_src_mac", config->dev_endpoint_src_mac, sizeof(config->dev_endpoint_src_mac)); + + if (config->rx_burst_max > RX_BURST_MAX) + { + LOG_ERROR("%s: invalid rx_burst_max, exceeds limit %d", LOG_TAG_PKTIO, RX_BURST_MAX); + return -1; + } + + if (strlen(config->app_symbol) == 0) + { + LOG_ERROR("%s: invalid app_symbol in %s", LOG_TAG_PKTIO, profile); + return -1; + } + + if (strlen(config->dev_endpoint) == 0) + { + LOG_ERROR("%s: invalid dev_endpoint in %s", LOG_TAG_PKTIO, profile); + return -1; + } + + if (strlen(config->dev_nf_interface) == 0) + { + LOG_ERROR("%s: invalid dev_nf_interface in %s", LOG_TAG_PKTIO, profile); + return -1; + } + + LOG_DEBUG("%s: PACKET_IO->bypass_all_traffic : %d", LOG_TAG_PKTIO, config->bypass_all_traffic); + LOG_DEBUG("%s: PACKET_IO->rx_burst_max : %d", LOG_TAG_PKTIO, config->rx_burst_max); + LOG_DEBUG("%s: PACKET_IO->app_symbol : %s", LOG_TAG_PKTIO, config->app_symbol); + LOG_DEBUG("%s: PACKET_IO->dev_endpoint : %s", LOG_TAG_PKTIO, config->dev_endpoint); + LOG_DEBUG("%s: PACKET_IO->dev_nf_interface : %s", LOG_TAG_PKTIO, config->dev_nf_interface); + LOG_DEBUG("%s: PACKET_IO->dev_endpoint_src_ip : %s", LOG_TAG_PKTIO, config->dev_endpoint_src_ip); + if (strlen(config->dev_endpoint_src_mac)) + { + LOG_DEBUG("%s: PACKET_IO->dev_endpoint_src_mac : %s (get from configuration file)", LOG_TAG_PKTIO, config->dev_endpoint_src_mac); + } + + return 0; +} + struct packet_io *packet_io_create(const char *profile, int thread_num, cpu_set_t *coremask) { int opt = 1; @@ -213,7 +1055,6 @@ struct packet_io *packet_io_create(const char *profile, int thread_num, cpu_set_ goto error_out; } - // Netwrok Function Interface handle->dev_nf_interface.mr_dev = marsio_open_device(handle->instance, handle->config.dev_nf_interface, handle->thread_num, handle->thread_num); if (handle->dev_nf_interface.mr_dev == NULL) { @@ -228,7 +1069,6 @@ struct packet_io *packet_io_create(const char *profile, int thread_num, cpu_set_ goto error_out; } - // EndPoint Interface handle->dev_endpoint.mr_dev = marsio_open_device(handle->instance, handle->config.dev_endpoint, handle->thread_num, handle->thread_num); if (handle->dev_endpoint.mr_dev == NULL) { @@ -315,97 +1155,13 @@ void packet_io_thread_wait(struct packet_io *handle, struct thread_ctx *thread_c marsio_poll_wait(handle->instance, vdevs, 2, thread_ctx->thread_index, timeout_ms); } -// return n_packet_recv -int packet_io_polling_nf_interface(struct packet_io *handle, int thread_seq, void *ctx) +int packet_io_thread_polling_nf(struct packet_io *handle, struct thread_ctx *thread_ctx) { - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + int thread_index = thread_ctx->thread_index; marsio_buff_t *rx_buffs[RX_BURST_MAX]; - // nr_recv <= rx_burst_max <= RX_BURST_MAX - int nr_recv = marsio_recv_burst(handle->dev_nf_interface.mr_dev, thread_seq, rx_buffs, handle->config.rx_burst_max); - if (nr_recv <= 0) - { - return 0; - } - - if (handle->config.bypass_all_traffic == 1) - { - for (int j = 0; j < nr_recv; j++) - { - if (!marsio_buff_is_ctrlbuf(rx_buffs[j])) - { - int raw_len = marsio_buff_datalen(rx_buffs[j]); - throughput_metrics_inc(&g_metrics->raw_pkt_rx, 1, raw_len); - throughput_metrics_inc(&g_metrics->raw_pkt_tx, 1, raw_len); - } - } - - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, rx_buffs, nr_recv); - return nr_recv; - } - - for (int j = 0; j < nr_recv; j++) - { - marsio_buff_t *rx_buff = rx_buffs[j]; - int raw_len = marsio_buff_datalen(rx_buff); - - if (is_downstream_keepalive_packet(rx_buff)) - { - throughput_metrics_inc(&g_metrics->downlink_keepalive_pkt_rx, 1, raw_len); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - continue; - } - - if (marsio_buff_is_ctrlbuf(rx_buff)) - { - handle_control_packet(handle, rx_buff, thread_seq, ctx); - throughput_metrics_inc(&g_metrics->ctrl_pkt_rx, 1, raw_len); - // all control packet need bypass - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - } - else - { - throughput_metrics_inc(&g_metrics->raw_pkt_rx, 1, raw_len); - int action_bytes = 0; - enum raw_pkt_action action = handle_raw_packet(handle, rx_buff, thread_seq, ctx, &action_bytes); - assert(action_bytes > 0); - switch (action) - { - case RAW_PKT_ERR_BYPASS: - throughput_metrics_inc(&g_metrics->raw_pkt_err_bypass, 1, action_bytes); - throughput_metrics_inc(&g_metrics->raw_pkt_tx, 1, raw_len); - break; - case RAW_PKT_HIT_BYPASS: - throughput_metrics_inc(&g_metrics->hit_bypass_policy, 1, action_bytes); - throughput_metrics_inc(&g_metrics->raw_pkt_tx, 1, raw_len); - break; - case RAW_PKT_HIT_BLOCK: - throughput_metrics_inc(&g_metrics->hit_block_policy, 1, action_bytes); - break; - case RAW_PKT_HIT_STEERING: - throughput_metrics_inc(&g_metrics->steering_tx, 1, action_bytes); - throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, action_bytes); - break; - case RAW_PKT_HIT_MIRRORING: - throughput_metrics_inc(&g_metrics->raw_pkt_tx, 1, action_bytes); - break; - } - } - } - - return nr_recv; -} - -// return n_packet_recv -int packet_io_polling_endpoint(struct packet_io *handle, int thread_seq, void *ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - - marsio_buff_t *rx_buffs[RX_BURST_MAX]; - // nr_recv <= rx_burst_max <= RX_BURST_MAX - int nr_recv = marsio_recv_burst(handle->dev_endpoint.mr_dev, thread_seq, rx_buffs, handle->config.rx_burst_max); + int nr_recv = marsio_recv_burst(handle->dev_nf_interface.mr_dev, thread_index, rx_buffs, handle->config.rx_burst_max); if (nr_recv <= 0) { return 0; @@ -416,1076 +1172,98 @@ int packet_io_polling_endpoint(struct packet_io *handle, int thread_seq, void *c for (int j = 0; j < nr_recv; j++) { int raw_len = marsio_buff_datalen(rx_buffs[j]); - throughput_metrics_inc(&g_metrics->dev_endpoint_rx, 1, raw_len); - throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, raw_len); + + throughput_metrics_inc(&(g_metrics->device.nf_rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->device.nf_tx), 1, raw_len); } - marsio_send_burst(handle->dev_endpoint.mr_path, thread_seq, rx_buffs, nr_recv); + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_index, rx_buffs, nr_recv); return nr_recv; } for (int j = 0; j < nr_recv; j++) { marsio_buff_t *rx_buff = rx_buffs[j]; - int data_len = marsio_buff_datalen(rx_buff); + int raw_len = marsio_buff_datalen(rx_buff); - if (is_upstream_keepalive_packet(rx_buff)) + if (is_downlink_keepalive_packet(rx_buff)) { - throughput_metrics_inc(&g_metrics->uplink_keepalive_pkt_rx, 1, data_len); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - continue; + throughput_metrics_inc(&(g_metrics->device.nf_rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->device.nf_tx), 1, raw_len); + + throughput_metrics_inc(&(g_metrics->kee_pkt.downlink_rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->kee_pkt.downlink_tx), 1, raw_len); + + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_index, &rx_buff, 1); } - - throughput_metrics_inc(&g_metrics->dev_endpoint_rx, 1, data_len); - int action_bytes = 0; - enum inject_pkt_action action = handle_inject_packet(handle, rx_buff, thread_seq, ctx, &action_bytes); - assert(action_bytes > 0); - switch (action) + else if (marsio_buff_is_ctrlbuf(rx_buff)) { - case INJT_PKT_ERR_DROP: - throughput_metrics_inc(&g_metrics->dev_endpoint_err_drop, 1, action_bytes); - break; - case INJT_PKT_MIRR_RX_DROP: - throughput_metrics_inc(&g_metrics->mirroring_rx_drop, 1, data_len); // use data_len - break; - case INJT_PKT_HIT_BLOCK: - throughput_metrics_inc(&g_metrics->steering_rx, 1, data_len); // use data_len - throughput_metrics_inc(&g_metrics->hit_block_policy, 1, action_bytes); - break; - case INJT_PKT_HIT_FWD2SF: // forward to next service function - throughput_metrics_inc(&g_metrics->steering_rx, 1, data_len); // use data_len - throughput_metrics_inc(&g_metrics->steering_tx, 1, action_bytes); // use action_bytes - throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, action_bytes); - break; - case INJT_PKT_HIT_FWD2NF: // forward to network function - throughput_metrics_inc(&g_metrics->steering_rx, 1, data_len); // use data_len - throughput_metrics_inc(&g_metrics->raw_pkt_tx, 1, action_bytes); - break; + throughput_metrics_inc(&(g_metrics->device.nf_rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->device.nf_tx), 1, raw_len); + + throughput_metrics_inc(&(g_metrics->ctrl_pkt.rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->ctrl_pkt.tx), 1, raw_len); + + handle_control_packet(rx_buff, thread_ctx); + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_index, &rx_buff, 1); + } + else + { + throughput_metrics_inc(&(g_metrics->device.nf_rx), 1, raw_len); + + handle_raw_packet(rx_buff, thread_ctx); } } return nr_recv; } -// return 0 : success -// return -1 : error -static int packet_io_config(const char *profile, struct config *config) +int packet_io_thread_polling_endpoint(struct packet_io *handle, struct thread_ctx *thread_ctx) { - MESA_load_profile_int_def(profile, "PACKET_IO", "bypass_all_traffic", (int *)&(config->bypass_all_traffic), 0); - MESA_load_profile_int_def(profile, "PACKET_IO", "rx_burst_max", (int *)&(config->rx_burst_max), 1); - MESA_load_profile_string_nodef(profile, "PACKET_IO", "app_symbol", config->app_symbol, sizeof(config->app_symbol)); - MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_endpoint", config->dev_endpoint, sizeof(config->dev_endpoint)); - MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_nf_interface", config->dev_nf_interface, sizeof(config->dev_nf_interface)); + struct global_metrics *g_metrics = thread_ctx->ref_metrics; + int thread_index = thread_ctx->thread_index; - MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_endpoint_src_ip", config->dev_endpoint_src_ip, sizeof(config->dev_endpoint_src_ip)); - MESA_load_profile_string_nodef(profile, "PACKET_IO", "dev_endpoint_src_mac", config->dev_endpoint_src_mac, sizeof(config->dev_endpoint_src_mac)); - - if (config->rx_burst_max > RX_BURST_MAX) + marsio_buff_t *rx_buffs[RX_BURST_MAX]; + int nr_recv = marsio_recv_burst(handle->dev_endpoint.mr_dev, thread_index, rx_buffs, handle->config.rx_burst_max); + if (nr_recv <= 0) { - LOG_ERROR("%s: invalid rx_burst_max, exceeds limit %d", LOG_TAG_PKTIO, RX_BURST_MAX); - return -1; + return 0; } - if (strlen(config->app_symbol) == 0) + if (handle->config.bypass_all_traffic == 1) { - LOG_ERROR("%s: invalid app_symbol in %s", LOG_TAG_PKTIO, profile); - return -1; - } - - if (strlen(config->dev_endpoint) == 0) - { - LOG_ERROR("%s: invalid dev_endpoint in %s", LOG_TAG_PKTIO, profile); - return -1; - } - - if (strlen(config->dev_nf_interface) == 0) - { - LOG_ERROR("%s: invalid dev_nf_interface in %s", LOG_TAG_PKTIO, profile); - return -1; - } - - LOG_DEBUG("%s: PACKET_IO->bypass_all_traffic : %d", LOG_TAG_PKTIO, config->bypass_all_traffic); - LOG_DEBUG("%s: PACKET_IO->rx_burst_max : %d", LOG_TAG_PKTIO, config->rx_burst_max); - LOG_DEBUG("%s: PACKET_IO->app_symbol : %s", LOG_TAG_PKTIO, config->app_symbol); - LOG_DEBUG("%s: PACKET_IO->dev_endpoint : %s", LOG_TAG_PKTIO, config->dev_endpoint); - LOG_DEBUG("%s: PACKET_IO->dev_nf_interface : %s", LOG_TAG_PKTIO, config->dev_nf_interface); - LOG_DEBUG("%s: PACKET_IO->dev_endpoint_src_ip : %s", LOG_TAG_PKTIO, config->dev_endpoint_src_ip); - if (strlen(config->dev_endpoint_src_mac)) - { - LOG_DEBUG("%s: PACKET_IO->dev_endpoint_src_mac : %s (get from configuration file)", LOG_TAG_PKTIO, config->dev_endpoint_src_mac); - } - - return 0; -} - -// return 0 : success -// return -1 : error -static int packet_io_get_metadata(marsio_buff_t *rx_buff, struct metadata *meta) -{ - memset(meta, 0, sizeof(struct metadata)); - - if (marsio_buff_get_metadata(rx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) <= 0) - { - LOG_ERROR("%s: unable to get session_id from metadata", LOG_TAG_PKTIO); - return -1; - } - - meta->raw_len = marsio_buff_datalen(rx_buff); - meta->raw_data = marsio_buff_mtod(rx_buff); - if (meta->raw_data == NULL || meta->raw_len == 0) - { - LOG_ERROR("%s: unable to get raw_data from metadata", LOG_TAG_PKTIO); - return -1; - } - - // 1: E2I - // 0: I2E - if (marsio_buff_get_metadata(rx_buff, MR_BUFF_DIR, &(meta->dir_is_e2i), sizeof(meta->dir_is_e2i)) <= 0) - { - LOG_ERROR("%s: unable to get buff_dir from metadata", LOG_TAG_PKTIO); - return -1; - } - - if (marsio_buff_is_ctrlbuf(rx_buff)) - { - meta->is_ctrl_pkt = 1; - // only control packet set MR_BUFF_PAYLOAD_OFFSET - if (marsio_buff_get_metadata(rx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7_offset), sizeof(meta->l7_offset)) <= 0) + for (int j = 0; j < nr_recv; j++) { - LOG_ERROR("%s: unable to get l7_offset from metadata", LOG_TAG_PKTIO); - return -1; - } - } - else - { - meta->is_ctrl_pkt = 0; - // only raw packet set MR_IS_DECRYPTED - // TODO -#if 0 - if (marsio_buff_get_metadata(rx_buff, MR_IS_DECRYPTED, &(meta->traffic_is_decrypted), sizeof(meta->traffic_is_decrypted)) <= 0) - { - LOG_ERROR("%s: unable to get traffic_is_decrypted from metadata", LOG_TAG_PKTIO); - return -1; - } -#endif - } + int raw_len = marsio_buff_datalen(rx_buffs[j]); - meta->route_ctx.len = marsio_buff_get_metadata(rx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, sizeof(meta->route_ctx.data)); - if (meta->route_ctx.len <= 0) - { - LOG_ERROR("%s: unable to get route_ctx from metadata", LOG_TAG_PKTIO); - return -1; - } - - meta->sids.num = marsio_buff_get_sid_list(rx_buff, meta->sids.elems, sizeof(meta->sids.elems) / sizeof(meta->sids.elems[0])); - if (meta->sids.num < 0) - { - LOG_ERROR("%s: unable to get sid_list from metadata", LOG_TAG_PKTIO); - return -1; - } - - return 0; -} - -// return 0 : success -// return -1 : error -static int packet_io_set_metadata(marsio_buff_t *tx_buff, struct metadata *meta) -{ - if (meta->session_id) - { - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id)) != 0) - { - LOG_ERROR("%s: unable to set session_id for metadata", LOG_TAG_PKTIO); - return -1; - } - } - - // 1: E2I - // 0: I2E -#if 0 - // use MR_BUFF_ROUTE_CTX instead - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_DIR, &(meta->dir_is_e2i), sizeof(meta->dir_is_e2i)) != 0) - { - LOG_ERROR("%s: unable to set buff_dir for metadata", LOG_TAG_PKTIO); - return -1; - } -#endif - - if (meta->is_ctrl_pkt) - { - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_PAYLOAD_OFFSET, &(meta->l7_offset), sizeof(meta->l7_offset)) != 0) - { - LOG_ERROR("%s: unable to set l7_offset for metadata", LOG_TAG_PKTIO); - return -1; - } - } - else - { - // TODO -#if 0 - if (marsio_buff_set_metadata(tx_buff, MR_IS_DECRYPTED, &(meta->traffic_is_decrypted), sizeof(meta->traffic_is_decrypted)) != 0) - { - LOG_ERROR("%s: unable to set traffic_is_decrypted for metadata", LOG_TAG_PKTIO); - return -1; - } -#endif - } - - if (meta->route_ctx.len > 0) - { - if (marsio_buff_set_metadata(tx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx.data, meta->route_ctx.len) != 0) - { - LOG_ERROR("%s: unable to set route_ctx for metadata", LOG_TAG_PKTIO); - return -1; - } - } - - if (meta->sids.num > 0) - { - if (marsio_buff_set_sid_list(tx_buff, meta->sids.elems, meta->sids.num) != 0) - { - LOG_ERROR("%s: unable to set sid_list for metadata", LOG_TAG_PKTIO); - return -1; - } - } - - return 0; -} - -static void packet_io_dump_metadata(marsio_buff_t *tx_buff, struct metadata *meta) -{ - LOG_DEBUG("%s: META={session_id: %lu, raw_len: %d, dir_is_e2i: %d, is_ctrl_pkt: %d, l7_offset: %d, traffic_is_decrypted: %d, sids_num: %d}", LOG_TAG_PKTIO, meta->session_id, meta->raw_len, meta->dir_is_e2i, meta->is_ctrl_pkt, meta->l7_offset, meta->traffic_is_decrypted, meta->sids.num); -} - -// return 0 : success -// return -1 : error -static int handle_control_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - struct sce_ctx *sce_ctx = thread->ref_sce_ctx; - - struct metadata meta; - if (packet_io_get_metadata(rx_buff, &meta) == -1) - { - LOG_ERROR("%s: unexpected control packet, unable to get metadata", LOG_TAG_PKTIO); - packet_io_dump_metadata(rx_buff, &meta); - __atomic_fetch_add(&g_metrics->ctrl_pkt_error_num, 1, __ATOMIC_RELAXED); - return -1; - } - - struct ctrl_pkt_parser ctrl_parser; - ctrl_packet_parser_init(&ctrl_parser); - if (ctrl_packet_parser_parse(&ctrl_parser, meta.raw_data + meta.l7_offset, meta.raw_len - meta.l7_offset) == -1) - { - LOG_ERROR("%s: unexpected control packet, unable to parse data", LOG_TAG_PKTIO); - __atomic_fetch_add(&g_metrics->ctrl_pkt_error_num, 1, __ATOMIC_RELAXED); - return -1; - } - - if (ctrl_parser.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_parser.session_id); - __atomic_fetch_add(&g_metrics->ctrl_pkt_error_num, 1, __ATOMIC_RELAXED); - return -1; - } - - if (sce_ctx->enable_debug) - { - LOG_INFO("%s: recv control packet, session %lu %s", LOG_TAG_PKTIO, ctrl_parser.session_id, session_state_to_string(ctrl_parser.state)); - } - - switch (ctrl_parser.state) - { - case SESSION_STATE_OPENING: - __atomic_fetch_add(&g_metrics->ctrl_pkt_opening_num, 1, __ATOMIC_RELAXED); - // when session opening, firewall not send policy id - // return handle_session_opening(&meta, &ctrl_parser, thread_seq, ctx); - break; - case SESSION_STATE_CLOSING: - __atomic_fetch_add(&g_metrics->ctrl_pkt_closing_num, 1, __ATOMIC_RELAXED); - return handle_session_closing(&meta, &ctrl_parser, thread_seq, ctx); - case SESSION_STATE_ACTIVE: - __atomic_fetch_add(&g_metrics->ctrl_pkt_active_num, 1, __ATOMIC_RELAXED); - return handle_session_active(&meta, &ctrl_parser, thread_seq, ctx); - case SESSION_STATE_RESETALL: - __atomic_fetch_add(&g_metrics->ctrl_pkt_resetall_num, 1, __ATOMIC_RELAXED); - return handle_session_resetall(&meta, &ctrl_parser, thread_seq, ctx); - default: - __atomic_fetch_add(&g_metrics->ctrl_pkt_error_num, 1, __ATOMIC_RELAXED); - } - - return 0; -} - -// return : RAW_PKT_ERR_BYPASS -// return : RAW_PKT_HIT_BYPASS -// return : RAW_PKT_HIT_BLOCK -// reutrn : RAW_PKT_HIT_STEERING -// return : RAW_PKT_HIT_MIRRORING -static enum raw_pkt_action handle_raw_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx, int *action_bytes) -{ - int nsend = 0; - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - struct sce_ctx *sce_ctx = thread->ref_sce_ctx; - - int raw_len = marsio_buff_datalen(rx_buff); - *action_bytes = 0; - - struct metadata meta; - if (packet_io_get_metadata(rx_buff, &meta) == -1) - { - LOG_ERROR("%s: unexpected raw packet, unable to get metadata, bypass !!!", LOG_TAG_PKTIO); - packet_io_dump_metadata(rx_buff, &meta); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } - - struct session_node *node = session_table_search_by_id(thread->session_table, meta.session_id); - if (node == NULL) - { - LOG_ERROR("%s: unexpected raw packet, unable to find session %lu from session table, bypass !!!", LOG_TAG_PKTIO, meta.session_id); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - - if (sce_ctx->enable_debug) - { - struct addr_tuple4 inner_addr; - struct addr_tuple4 reverse_addr; - struct raw_pkt_parser raw_parser; - memset(&inner_addr, 0, sizeof(struct addr_tuple4)); - memset(&reverse_addr, 0, sizeof(struct addr_tuple4)); - raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); - raw_packet_parser_parse(&raw_parser, (const void *)meta.raw_data, meta.raw_len); - raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); - addr_tuple4_reverse(&inner_addr, &reverse_addr); - if (memcmp(&s_ctx->first_ctrl_pkt.tuple4, &inner_addr, sizeof(struct addr_tuple4)) != 0 && memcmp(&s_ctx->first_ctrl_pkt.tuple4, &reverse_addr, sizeof(struct addr_tuple4)) != 0) - { - char *addr_str = addr_tuple4_to_str(&inner_addr); - LOG_ERROR("%s: unexpected raw packet, session %lu expected address tuple4 to be %s, but now the packet's tuple4 is %s, bypass !!!", LOG_TAG_PKTIO, meta.session_id, s_ctx->first_ctrl_pkt.addr_string, addr_str); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - free(addr_str); - return RAW_PKT_ERR_BYPASS; - } - } - - // update sids - if (meta.dir_is_e2i) - { - sids_write_once(&(s_ctx->raw_pkt_e2i_sids), &(meta.sids)); - if (route_ctx_is_empty(&s_ctx->raw_pkt_e2i_route_ctx)) - { - route_ctx_copy(&s_ctx->raw_pkt_e2i_route_ctx, &meta.route_ctx); - } - } - else - { - sids_write_once(&(s_ctx->raw_pkt_i2e_sids), &(meta.sids)); - if (route_ctx_is_empty(&s_ctx->raw_pkt_i2e_route_ctx)) - { - route_ctx_copy(&s_ctx->raw_pkt_i2e_route_ctx, &meta.route_ctx); - } - } - - // search chaining - struct selected_chaining *chaining = s_ctx->chaining; - if (chaining == NULL) - { - LOG_ERROR("%s: unexpected raw packet, session %lu %s misses policy, bypass !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } - - int last_sf_is_action_bypass = 1; - for (int i = 0; i < chaining->chaining_used; i++) - { - struct selected_sf *node = &(chaining->chaining[i]); - LOG_INFO("%s: session %lu %s execute policy: %d -> sff_profile_id %d -> sf_profile_id %d -> sf_need_skip %d sf_action_reason : %s", - LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string, node->policy_id, node->sff_profile_id, node->sf_profile_id, node->sf_need_skip, session_action_reason_to_string(node->sf_action_reason)); - - if (node->sf_need_skip) - { - continue; + throughput_metrics_inc(&(g_metrics->device.endpoint_rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->device.endpoint_tx), 1, raw_len); } - switch (node->sf_action) + marsio_send_burst(handle->dev_endpoint.mr_path, thread_index, rx_buffs, nr_recv); + return nr_recv; + } + + for (int j = 0; j < nr_recv; j++) + { + marsio_buff_t *rx_buff = rx_buffs[j]; + int raw_len = marsio_buff_datalen(rx_buff); + + if (is_uplink_keepalive_packet(rx_buff)) { - case SESSION_ACTION_BYPASS: - // BYPASS CURRENT SF - last_sf_is_action_bypass = 1; - continue; - case SESSION_ACTION_BLOCK: - if (node->sff_forward_type == FORWARD_TYPE_STEERING) - { - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - } - else - { - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - throughput_metrics_inc(&g_metrics->raw_pkt_tx, 1, raw_len); - } - *action_bytes = raw_len; - return RAW_PKT_HIT_BLOCK; - case SESSION_ACTION_FORWARD: - if (node->sf_connectivity.method != PACKAGE_METHOD_VXLAN_G) - { - LOG_ERROR("%s: processing raw packets, session %lu %s requires encapsulation format not supported, bypass !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } + throughput_metrics_inc(&(g_metrics->device.endpoint_rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->kee_pkt.uplink_rx), 1, raw_len); + throughput_metrics_inc(&(g_metrics->kee_pkt.uplink_tx_drop), 1, raw_len); - if (node->sff_forward_type == FORWARD_TYPE_STEERING) - { - // rx_buff : not include g_vxlan header - // return + : send n bytes - // return -1 : error - nsend = forward_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx); - if (nsend > 0) - { - sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend); - throughput_metrics_inc(&node->tx, 1, nsend); - *action_bytes = nsend; - return RAW_PKT_HIT_STEERING; - } - else - { - LOG_ERROR("%s: processing raw packet, session %lu %s forwarding packet to service function failed, bypass !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } - } - else - { - // rx_buff : not include g_vxlan header - // return + : send n bytes - // return -1 : error - nsend = mirror_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx); - if (nsend > 0) - { - sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend); - throughput_metrics_inc(&node->tx, 1, nsend); - throughput_metrics_inc(&g_metrics->mirroring_tx, 1, nsend); - throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, nsend); - last_sf_is_action_bypass = 0; - continue; - } - else - { - LOG_ERROR("%s: processing raw packet, session %lu %s mirroring packet to service function failed, bypass !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - return RAW_PKT_ERR_BYPASS; - } - } - - default: - last_sf_is_action_bypass = 1; - continue; - } - } - - marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); - *action_bytes = raw_len; - - if (last_sf_is_action_bypass) - { - // BYPASS ALL SF or LAST SF IS MIRRORING - return RAW_PKT_HIT_BYPASS; - } - else - { - return RAW_PKT_HIT_MIRRORING; - } -} - -// return : INJT_PKT_ERR_DROP -// return : INJT_PKT_MIRR_RX_DROP -// return : INJT_PKT_HIT_BLOCK -// return : INJT_PKT_HIT_FWD2SF -// return : INJT_PKT_HIT_FWD2NF -static enum inject_pkt_action handle_inject_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx, int *action_bytes) -{ - int nsend = 0; - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - - struct g_vxlan *g_vxlan_hdr = NULL; - int raw_len = marsio_buff_datalen(rx_buff); - char *raw_data = marsio_buff_mtod(rx_buff); - *action_bytes = 0; - if (g_vxlan_decode(&g_vxlan_hdr, raw_data, raw_len) == -1) - { - // LOG_ERROR("%s: unexpected inject packet, not a vxlan-encapsulated packet, drop !!!", LOG_TAG_PKTIO); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - - struct metadata meta; - memset(&meta, 0, sizeof(struct metadata)); - meta.raw_data = (char *)g_vxlan_hdr + sizeof(struct g_vxlan); - meta.raw_len = raw_len - sizeof(struct ethhdr) - sizeof(struct ip) - sizeof(struct udp_hdr) - sizeof(struct g_vxlan); - meta.dir_is_e2i = g_vxlan_get_packet_dir(g_vxlan_hdr); - meta.traffic_is_decrypted = g_vxlan_get_traffic_type(g_vxlan_hdr); - meta.is_ctrl_pkt = 0; - meta.l7_offset = 0; - // meta.session_id set later - // meta.sids set later - int sf_index = g_vxlan_get_sf_index(g_vxlan_hdr); - - struct addr_tuple4 inner_addr; - struct raw_pkt_parser raw_parser; - memset(&inner_addr, 0, sizeof(struct addr_tuple4)); - raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8); - raw_packet_parser_parse(&raw_parser, (const void *)meta.raw_data, meta.raw_len); - raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_addr); - - struct session_node *node = session_table_search_by_addr(thread->session_table, &inner_addr); - if (node == NULL) - { - char *addr_string = addr_tuple4_to_str(&inner_addr); - LOG_ERROR("%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_string); - free(addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - meta.session_id = s_ctx->session_id; - if (meta.dir_is_e2i) - { - sids_copy(&meta.sids, &s_ctx->raw_pkt_e2i_sids); - route_ctx_copy(&meta.route_ctx, &s_ctx->raw_pkt_e2i_route_ctx); - } - else - { - sids_copy(&meta.sids, &s_ctx->raw_pkt_i2e_sids); - route_ctx_copy(&meta.route_ctx, &s_ctx->raw_pkt_i2e_route_ctx); - } - LOG_DEBUG("%s: session %lu get metadata from inject packet, META={raw_len: %d, dir_is_e2i: %d, traffic_is_decrypted: %d, sf_index: %d}", LOG_TAG_PKTIO, meta.session_id, meta.raw_len, meta.dir_is_e2i, meta.traffic_is_decrypted, sf_index); - - struct selected_chaining *chaining = s_ctx->chaining; - if (chaining == NULL || sf_index < 0 || sf_index >= chaining->chaining_used) - { - LOG_ERROR("%s: unexpected inject packet, session %lu %s misses chaining index, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - - if (chaining->chaining[sf_index].sff_forward_type == FORWARD_TYPE_MIRRORING) - { - LOG_DEBUG("%s: unexpected inject packet, session %lu %s with sf_profile_id %d executes mirror and does not require reflow, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string, chaining->chaining[sf_index].sf_profile_id); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_MIRR_RX_DROP; - } - - sf_metrics_inc(thread->sf_metrics, chaining->chaining[sf_index].policy_id, chaining->chaining[sf_index].sff_profile_id, chaining->chaining[sf_index].sf_profile_id, 1, raw_len, 0, 0); - throughput_metrics_inc(&chaining->chaining[sf_index].rx, 1, raw_len); - - marsio_buff_adj(rx_buff, raw_len - meta.raw_len); - int next_sf_index; - for (next_sf_index = sf_index + 1; next_sf_index < chaining->chaining_used; next_sf_index++) - { - struct selected_sf *node = &(chaining->chaining[next_sf_index]); - LOG_INFO("%s: session %lu %s execute policy: %d -> sff_profile_id %d -> sf_profile_id %d -> sf_need_skip %d sf_action_reason : %s", - LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string, node->policy_id, node->sff_profile_id, node->sf_profile_id, node->sf_need_skip, session_action_reason_to_string(node->sf_action_reason)); - - if (node->sf_need_skip) - { - continue; - } - - switch (node->sf_action) - { - case SESSION_ACTION_BYPASS: - // BYPASS CURRENT SF - continue; - case SESSION_ACTION_BLOCK: - if (node->sff_forward_type == FORWARD_TYPE_STEERING) - { - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_HIT_BLOCK; - } - else - { - // rx_buff : not include g_vxlan header - // return + : send n bytes - // return -1 : error - int nsend = forward_packet_to_nf(handle, rx_buff, &meta, thread_seq, ctx); - if (nsend > 0) - { - *action_bytes = raw_len; - throughput_metrics_inc(&g_metrics->raw_pkt_tx, 1, nsend); - return INJT_PKT_HIT_BLOCK; - } - else - { - LOG_ERROR("%s: processing inject packet, session %lu %s forwarding packet to network function failed, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - } - case SESSION_ACTION_FORWARD: - if (node->sf_connectivity.method != PACKAGE_METHOD_VXLAN_G) - { - LOG_ERROR("%s: processing inject packets, session %lu %s requires encapsulation format not supported, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - - if (node->sff_forward_type == FORWARD_TYPE_STEERING) - { - // rx_buff : not include g_vxlan header - // return + : send n bytes - // return -1 : error - nsend = forward_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx); - if (nsend > 0) - { - sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend); - throughput_metrics_inc(&node->tx, 1, nsend); - *action_bytes = nsend; - return INJT_PKT_HIT_FWD2SF; - } - else - { - LOG_ERROR("%s: processing inject packet, session %lu %s forwarding packet to service function failed, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - } - else - { - // rx_buff : not include g_vxlan header - // return + : send n bytes - // return -1 : error - nsend = mirror_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx); - if (nsend > 0) - { - sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend); - throughput_metrics_inc(&node->tx, 1, nsend); - throughput_metrics_inc(&g_metrics->mirroring_tx, 1, nsend); - throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, nsend); - continue; - } - else - { - LOG_ERROR("%s: processing inject packet, session %lu %s mirroring packet to service function failed, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - } - - default: - assert(0); - continue; - } - } - - // the last sf need bypass or need skip - if (next_sf_index != chaining->chaining_used) - { - LOG_ERROR("%s: unexpected inject packet, session %lu %s using invalid chaining index, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - else - { - // rx_buff : not include g_vxlan header - // return + : send n bytes - // return -1 : error - int nsend = forward_packet_to_nf(handle, rx_buff, &meta, thread_seq, ctx); - if (nsend > 0) - { - *action_bytes = nsend; - return INJT_PKT_HIT_FWD2NF; + marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_index); } else { - LOG_ERROR("%s: processing inject packet, session %lu %s forwarding packet to network function failed, drop !!!", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); - *action_bytes = raw_len; - return INJT_PKT_ERR_DROP; - } - } -} + throughput_metrics_inc(&(g_metrics->device.endpoint_rx), 1, raw_len); -// rx_buff : not include g_vxlan header -// return + : send n bytes -// return -1 : error -static int forward_packet_to_sf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, int thread_seq, void *ctx) -{ - marsio_buff_ctrlzone_reset(rx_buff); - - struct ethhdr *eth_hdr = (struct ethhdr *)marsio_buff_prepend(rx_buff, sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udp_hdr) + sizeof(struct g_vxlan)); - struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr)); - struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ip)); - struct g_vxlan *g_vxlan_hdr = (struct g_vxlan *)((char *)udp_hdr + sizeof(struct udp_hdr)); - - LOG_DEBUG("%s: session %lu set metadata to inject packet, META={raw_len: %d, dir_is_e2i: %d, traffic_is_decrypted: %d, sf_index: %d}", LOG_TAG_PKTIO, meta->session_id, meta->raw_len, meta->dir_is_e2i, meta->traffic_is_decrypted, sf->sf_index); - - memset(g_vxlan_hdr, 0, sizeof(struct g_vxlan)); - g_vxlan_set_packet_dir(g_vxlan_hdr, meta->dir_is_e2i); - g_vxlan_set_sf_index(g_vxlan_hdr, sf->sf_index); - g_vxlan_set_traffic_type(g_vxlan_hdr, meta->traffic_is_decrypted); - - build_ether_header(eth_hdr, ETH_P_IP, handle->config.dev_endpoint_src_mac, sf->sf_dst_mac); - build_ip_header(ip_hdr, IPPROTO_UDP, handle->config.dev_endpoint_src_ip, sf->sf_dst_ip, sizeof(struct udp_hdr) + sizeof(struct g_vxlan) + meta->raw_len); - build_udp_header((const char *)&ip_hdr->ip_src, 8, udp_hdr, meta->session_id % (65535 - 49152) + 49152, 4789, sizeof(struct g_vxlan) + meta->raw_len); - - int raw_len = marsio_buff_datalen(rx_buff); - if (marsio_send_burst(handle->dev_endpoint.mr_path, thread_seq, &rx_buff, 1) != 0) - { - LOG_ERROR("%s: unable to send burst on device %s, thread_seq: %d", LOG_TAG_PKTIO, handle->config.dev_endpoint, thread_seq); - return -1; - } - - return raw_len; -} - -// rx_buff : not include g_vxlan header -// return + : send n bytes -// return -1 : error -static int mirror_packet_to_sf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, int thread_seq, void *ctx) -{ - marsio_buff_t *new_buff = NULL; - if (marsio_buff_malloc_global(handle->instance, &new_buff, 1, MARSIO_SOCKET_ID_ANY, MARSIO_LCORE_ID_ANY) < 0) - { - LOG_ERROR("%s: unable to malloc buff on marsio instance, thread_seq: %d", LOG_TAG_PKTIO, thread_seq); - return -1; - } - - unsigned int raw_len = marsio_buff_datalen(rx_buff); - const char *raw_data = marsio_buff_mtod(rx_buff); - char *copy_ptr = marsio_buff_append(new_buff, raw_len); - memcpy(copy_ptr, raw_data, raw_len); - - int nsend = forward_packet_to_sf(handle, new_buff, meta, sf, thread_seq, ctx); - if (nsend == -1) - { - marsio_buff_free(handle->instance, &new_buff, 1, 0, thread_seq); - } - - return nsend; -} - -// rx_buff : not include g_vxlan header -// return + : send n bytes -// return -1 : error -static int forward_packet_to_nf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, int thread_seq, void *ct) -{ - marsio_buff_ctrlzone_reset(rx_buff); - if (packet_io_set_metadata(rx_buff, meta) != 0) - { - return -1; - } - - int raw_len = marsio_buff_datalen(rx_buff); - if (marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1) != 0) - { - LOG_ERROR("%s: unable to send burst on device %s, thread_seq: %d", LOG_TAG_PKTIO, handle->config.dev_nf_interface, thread_seq); - return -1; - } - - return raw_len; -} - -// return 0 : success -// return -1 : error -static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - - if (session_table_search_by_id(thread->session_table, meta->session_id)) - { - return -1; - } - - struct raw_pkt_parser raw_parser; - raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); - if ((char *)payload - (char *)&meta->raw_data != meta->l7_offset) - { - LOG_ERROR("%s: incorrect dataoffset in the control zone of session %lu", LOG_TAG_PKTIO, meta->session_id); - } - - struct session_ctx *s_ctx = session_ctx_new(); - s_ctx->ref_thread_ctx = thread; - fixed_num_array_init(&s_ctx->policy_ids); - s_ctx->session_id = meta->session_id; - s_ctx->first_ctrl_pkt.dir_is_e2i = meta->dir_is_e2i; - raw_packet_parser_get_most_inner_tuple4(&raw_parser, &(s_ctx->first_ctrl_pkt.tuple4)); - s_ctx->first_ctrl_pkt.addr_string = addr_tuple4_to_str(&(s_ctx->first_ctrl_pkt.tuple4)); - s_ctx->first_ctrl_pkt.header_data = strndup(meta->raw_data, meta->l7_offset); - s_ctx->first_ctrl_pkt.header_len = meta->l7_offset; - sids_copy(&s_ctx->first_ctrl_pkt.sids, &meta->sids); - route_ctx_copy(&s_ctx->first_ctrl_pkt.route_ctx, &meta->route_ctx); - - s_ctx->chaining = selected_chaining_create(policy_enforce_max_chaining_size(thread->ref_enforcer)); - - LOG_INFO("%s: session %lu %s active first", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - - for (int i = 0; i < parser->policy_id_num; i++) - { - int new_policy_id = parser->policy_ids[i]; - if (fixed_num_array_exist_elem(&s_ctx->policy_ids, new_policy_id)) - { - continue; - } - else - { - policy_enforce_select_chaining(s_ctx->chaining, thread->ref_enforcer, &raw_parser, new_policy_id, meta->dir_is_e2i, s_ctx); - selected_chaining_bref(s_ctx->chaining); - fixed_num_array_add_elem(&s_ctx->policy_ids, new_policy_id); + handle_inject_packet(rx_buff, thread_ctx); } } - __atomic_fetch_add(&g_metrics->session_nums, 1, __ATOMIC_RELAXED); - session_table_insert(thread->session_table, s_ctx->session_id, &(s_ctx->first_ctrl_pkt.tuple4), s_ctx, session_value_free_cb); - - return 0; + return nr_recv; } - -/* -{ - "tsync": "1.0", - "session_id": "123456789", - "state": "active", - "method": "log_update", - "params": { - "sf_profile_ids": [ - 2, - 3, - 4, - 5, - 6, - 7 - ] - } -} -*/ -static void send_event_log(struct session_ctx *s_ctx, int thread_seq, void *ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct sce_ctx *sce_ctx = thread->ref_sce_ctx; - struct packet_io *packet_io = thread->ref_io; - struct selected_chaining *chaining = s_ctx->chaining; - - char buffer[32] = {0}; - sprintf(buffer, "%lu", s_ctx->session_id); - - cJSON *root = cJSON_CreateObject(); - cJSON_AddStringToObject(root, "tsync", "1.0"); - cJSON_AddStringToObject(root, "session_id", buffer); - cJSON_AddStringToObject(root, "state", "closing"); - cJSON_AddStringToObject(root, "method", "log_update"); - cJSON *sf_profile_ids = cJSON_CreateArray(); - for (int i = 0; i < chaining->chaining_used; i++) - { - struct selected_sf *node = &(chaining->chaining[i]); - if (node->sf_need_skip == 0 && node->sf_action == SESSION_ACTION_FORWARD) - { - cJSON *id = cJSON_CreateNumber(node->sf_profile_id); - cJSON_AddItemToArray(sf_profile_ids, id); - } - } - cJSON *params = cJSON_CreateObject(); - cJSON_AddItemToObject(params, "sf_profile_ids", sf_profile_ids); - cJSON_AddItemToObject(root, "params", params); - char *json_str = cJSON_PrintUnformatted(root); - - LOG_INFO("%s: session %lu %s event log: %s", LOG_TAG_METRICS, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string, json_str); - - marsio_buff_t *tx_buffs[1]; - marsio_buff_malloc_device(packet_io->dev_nf_interface.mr_dev, tx_buffs, 1, 0, thread_seq); - char *dst = marsio_buff_append(tx_buffs[0], s_ctx->first_ctrl_pkt.header_len + strlen(json_str)); - memcpy(dst, s_ctx->first_ctrl_pkt.header_data, s_ctx->first_ctrl_pkt.header_len); - memcpy(dst + s_ctx->first_ctrl_pkt.header_len, json_str, strlen(json_str)); - - struct metadata meta = {0}; - meta.session_id = s_ctx->session_id; - meta.is_ctrl_pkt = 1; - meta.l7_offset = s_ctx->first_ctrl_pkt.header_len; - meta.sids.num = 1; - meta.sids.elems[0] = sce_ctx->firewall_sids; - route_ctx_copy(&meta.route_ctx, &s_ctx->first_ctrl_pkt.route_ctx); - packet_io_set_metadata(tx_buffs[0], &meta); - marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread_seq, tx_buffs, 1); - - free(json_str); - cJSON_Delete(root); -} - -// return 0 : success -// return -1 : error -static int handle_session_closing(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - - struct session_node *node = session_table_search_by_id(thread->session_table, meta->session_id); - if (node) - { - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - LOG_INFO("%s: session %lu %s closing", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - struct selected_chaining *chaining = s_ctx->chaining; - - for (int i = 0; i < chaining->chaining_used; i++) - { - struct selected_sf *node = &(chaining->chaining[i]); - LOG_INFO("%s: session %lu %s metrics log: policy %d sff_profile_id %d sf_profile_id %d sf_need_skip %d sf_action_reason %s rx_pkts %lu rx_bytes %lu tx_pkts %lu tx_bytes %lu", LOG_TAG_METRICS, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string, node->policy_id, node->sff_profile_id, node->sf_profile_id, node->sf_need_skip, session_action_reason_to_string(node->sf_action_reason), node->rx.n_pkts, node->rx.n_bytes, node->tx.n_pkts, node->tx.n_bytes); - } - - send_event_log(s_ctx, thread_seq, ctx); - __atomic_fetch_add(&g_metrics->send_log, 1, __ATOMIC_RELAXED); - - __atomic_fetch_sub(&g_metrics->session_nums, 1, __ATOMIC_RELAXED); - session_table_delete_by_id(thread->session_table, meta->session_id); - return 0; - } - - return -1; -} - -// return 0 : success -// return -1 : error -static int handle_session_active(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)ctx; - // struct global_metrics *g_metrics = thread->ref_metrics; - - struct session_node *node = session_table_search_by_id(thread->session_table, meta->session_id); - if (node) - { - struct raw_pkt_parser raw_parser; - raw_packet_parser_init(&raw_parser, meta->session_id, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(&raw_parser, (const void *)meta->raw_data, meta->raw_len); - if ((char *)payload - (char *)&meta->raw_data != meta->l7_offset) - { - LOG_ERROR("%s: incorrect dataoffset in the control zone of session %lu", LOG_TAG_PKTIO, meta->session_id); - } - - struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; - LOG_INFO("%s: session %lu %s active again", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); - - for (int i = 0; i < parser->policy_id_num; i++) - { - int new_policy_id = parser->policy_ids[i]; - if (fixed_num_array_exist_elem(&s_ctx->policy_ids, new_policy_id)) - { - continue; - } - else - { - policy_enforce_select_chaining(s_ctx->chaining, thread->ref_enforcer, &raw_parser, new_policy_id, meta->dir_is_e2i, s_ctx); - selected_chaining_bref(s_ctx->chaining); - fixed_num_array_add_elem(&s_ctx->policy_ids, new_policy_id); - } - } - } - else - { - return handle_session_opening(meta, parser, thread_seq, ctx); - } - - return 0; -} - -// return 0 : success -// return -1 : error -static int handle_session_resetall(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - struct sce_ctx *sce_ctx = thread->ref_sce_ctx; - - LOG_ERROR("%s: session %lu resetall: notification clears all session tables !!!", LOG_TAG_PKTIO, meta->session_id); - - __atomic_fetch_and(&g_metrics->session_nums, 0, __ATOMIC_RELAXED); - - for (int i = 0; i < sce_ctx->nr_worker_threads; i++) - { - struct thread_ctx *thread_ctx = &sce_ctx->work_threads[i]; - __atomic_fetch_add(&thread_ctx->session_table_need_reset, 1, __ATOMIC_RELAXED); - } - - return 0; -} - -static void session_value_free_cb(void *ctx) -{ - struct session_ctx *s_ctx = (struct session_ctx *)ctx; - session_ctx_free(s_ctx); -} - -// return 0 : not keepalive packet -// return 1 : is keepalive packet -static int is_downstream_keepalive_packet(marsio_buff_t *rx_buff) -{ - int raw_len = marsio_buff_datalen(rx_buff); - char *raw_data = marsio_buff_mtod(rx_buff); - if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr))) - { - return 0; - } - - struct ethhdr *eth_hdr = (struct ethhdr *)raw_data; - if (eth_hdr->h_proto == 0xAAAA) - { - return 1; - } - else - { - return 0; - } -} - -// return 0 : not keepalive packet -// return 1 : is keepalive packet -static int is_upstream_keepalive_packet(marsio_buff_t *rx_buff) -{ - int raw_len = marsio_buff_datalen(rx_buff); - char *raw_data = marsio_buff_mtod(rx_buff); - if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udp_hdr))) - { - return 0; - } - - struct ethhdr *eth_hdr = (struct ethhdr *)raw_data; - if (eth_hdr->h_proto != htons(ETH_P_IP)) - { - return 0; - } - - struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr)); - if (ip_hdr->ip_p != IPPROTO_UDP) - { - return 0; - } - - struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ip)); - if (udp_hdr->uh_dport != htons(3784)) - { - return 0; - } - - return 1; -} \ No newline at end of file diff --git a/platform/src/policy.cpp b/platform/src/policy.cpp index 8db3015..c708f4a 100644 --- a/platform/src/policy.cpp +++ b/platform/src/policy.cpp @@ -150,88 +150,14 @@ struct sf_param * Private API ******************************************************************************/ -static const char *traffic_type_to_string(enum traffic_type traffic_type) +static const char *admin_status_to_string(enum admin_status admin_status) { - switch (traffic_type) + switch (admin_status) { - case TRAFFIC_TYPE_NONE: - return "none"; - case TRAFFIC_TYPE_RAW: - return "raw"; - case TRAFFIC_TYPE_DECRYPTED: - return "decrypted"; - default: - return "unknown"; - } -} - -static const char *forward_type_to_string(enum forward_type forward_type) -{ - switch (forward_type) - { - case FORWARD_TYPE_NONE: - return "none"; - case FORWARD_TYPE_STEERING: - return "steering"; - case FORWARD_TYPE_MIRRORING: - return "mirroring"; - default: - return "unknown"; - } -} - -static const char *session_action_to_string(enum session_action session_action) -{ - switch (session_action) - { - case SESSION_ACTION_BYPASS: - return "bypass"; - case SESSION_ACTION_FORWARD: - return "forward"; - case SESSION_ACTION_BLOCK: - return "block"; - default: - return "unknown"; - } -} - -const char *session_action_reason_to_string(enum session_action_reason session_action_reason) -{ - switch (session_action_reason) - { - case ACTION_BYPASS_DUE_DEFAULT: - return "bypass_due_default"; - case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT: - return "bypass_due_health_sf_limit"; - case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION: - return "bypass_due_unavailable_action"; - case ACTION_BYPASS_DUE_FAILURE_ACTION: - return "bypass_due_failure_action"; - case ACTION_BYPASS_DUE_INVALID_POLICY: - return "bypass_due_invalid_policy"; - case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION: - return "block_due_unavailable_action"; - case ACTION_BLOCK_DUE_FAILURE_ACTION: - return "block_due_failure_action"; - case ACTION_FORWAED_DUE_SELECTED_AVAILABLE_SF: - return "forward_due_selected_available_sf"; - default: - return "unknown"; - } -} - -static const char *package_method_to_string(enum package_method package_method) -{ - switch (package_method) - { - case PACKAGE_METHOD_NONE: - return "none"; - case PACKAGE_METHOD_LAYER2_SWITCH: - return "layer2_switch"; - case PACKAGE_METHOD_LAYER3_SWITCH: - return "layer3_switch"; - case PACKAGE_METHOD_VXLAN_G: - return "vxlan_g"; + case ADMMIN_STATUS_ACTIVE: + return "active"; + case ADMMIN_STATUS_INACTIVE: + return "inactive"; default: return "unknown"; } @@ -380,12 +306,10 @@ static void chaining_param_new_cb(int table_id, const char *key, const char *tab } if (strcasecmp(item->valuestring, "raw") == 0) { - LOG_DEBUG("%s: parse chaining policy: %d, targeted_traffic: raw", LOG_TAG_POLICY, param->policy_id); param->traffic_type = TRAFFIC_TYPE_RAW; } else if (strcasecmp(item->valuestring, "decrypted") == 0) { - LOG_DEBUG("%s: parse chaining policy: %d, targeted_traffic: decrypted", LOG_TAG_POLICY, param->policy_id); param->traffic_type = TRAFFIC_TYPE_DECRYPTED; } else @@ -393,6 +317,7 @@ static void chaining_param_new_cb(int table_id, const char *key, const char *tab LOG_ERROR("%s: unexpected chaining policy: (invalid targeted_traffic param) %s", LOG_TAG_POLICY, table_line); goto error_out; } + LOG_DEBUG("%s: parse chaining policy: %d, targeted_traffic: %s", LOG_TAG_POLICY, param->policy_id, traffic_type_to_string(param->traffic_type)); // sff_profiles item = cJSON_GetObjectItem(json, "sff_profiles"); @@ -525,16 +450,15 @@ static void sff_param_new_cb(int table_id, const char *key, const char *table_li { case 1: param->sff_forward_type = FORWARD_TYPE_STEERING; - LOG_DEBUG("%s: parse sff profile: %d, type: steering", LOG_TAG_POLICY, param->sff_profile_id); break; case 2: param->sff_forward_type = FORWARD_TYPE_MIRRORING; - LOG_DEBUG("%s: parse sff profile: %d, type: mirroring", LOG_TAG_POLICY, param->sff_profile_id); break; default: LOG_ERROR("%s: unexpected sff profile: (invalid type param) %s", LOG_TAG_POLICY, table_line); goto error_out; } + LOG_DEBUG("%s: parse sff profile: %d, type: %s", LOG_TAG_POLICY, param->sff_profile_id, forward_type_to_string(param->sff_forward_type)); // load_balance_method if (0 == strcasecmp(load_balance_method, "hash-int-ip")) @@ -762,16 +686,15 @@ static void sf_param_new_cb(int table_id, const char *key, const char *table_lin { case 1: param->sf_admin_status = ADMMIN_STATUS_ACTIVE; - LOG_DEBUG("%s: parse sf profile: %d, admin_status: active", LOG_TAG_POLICY, param->sf_profile_id); break; case 0: param->sf_admin_status = ADMMIN_STATUS_INACTIVE; - LOG_DEBUG("%s: parse sf profile: %d, admin_status: inactive", LOG_TAG_POLICY, param->sf_profile_id); break; default: LOG_ERROR("%s: unexpected sf profile: (invalid admin_status param) %s", LOG_TAG_POLICY, table_line); goto error_out; } + LOG_DEBUG("%s: parse sf profile: %d, admin_status: %s", LOG_TAG_POLICY, param->sf_profile_id, admin_status_to_string(param->sf_admin_status)); // connectivity root1 = cJSON_Parse(connectivity); @@ -804,7 +727,7 @@ static void sf_param_new_cb(int table_id, const char *key, const char *table_lin LOG_ERROR("%s: unexpected sf profile: (invalid connectivity->method param) %s", LOG_TAG_POLICY, table_line); goto error_out; } - LOG_DEBUG("%s: parse sf profile: %d, connectivity->method: %s", LOG_TAG_POLICY, param->sf_profile_id, item->valuestring); + LOG_DEBUG("%s: parse sf profile: %d, connectivity->method: %s", LOG_TAG_POLICY, param->sf_profile_id, package_method_to_string(param->sf_connectivity.method)); if (param->sf_connectivity.method == PACKAGE_METHOD_LAYER2_SWITCH || param->sf_connectivity.method == PACKAGE_METHOD_LAYER3_SWITCH) { @@ -979,7 +902,7 @@ static void sf_param_free(struct sf_param *param) } // After return must check array elem nums -static void select_sf_by_nearby_and_active(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct fixed_num_array *array) +static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct fixed_num_array *array) { char buffer[16]; struct sf_param *sf = NULL; @@ -1019,14 +942,14 @@ static void select_sf_by_nearby_and_active(struct policy_enforcer *enforcer, str // return : SESSION_ACTION_BYPASS, not care selected_sf_profile_id // return : SESSION_ACTION_BLOCK, not care selected_sf_profile_id // return : SESSION_ACTION_FORWARD, care selected_sf_profile_id -static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforcer *enforcer, struct sff_param *sff_param, struct fixed_num_array *array, int *selected_sf_profile_id, enum session_action_reason *sf_action_reason, char *sf_dst_mac, struct session_ctx *s_ctx) +static enum session_action select_sf_by_ldbc(struct policy_enforcer *enforcer, struct session_ctx *s_ctx, struct sff_param *sff_param, struct selected_sf *sf, struct fixed_num_array *array, uint64_t hash) { struct thread_ctx *thread = (struct thread_ctx *)s_ctx->ref_thread_ctx; struct global_metrics *g_metrics = thread->ref_metrics; - struct sf_param *sf = NULL; + struct sf_param *sf_param = NULL; char buffer[16]; - *selected_sf_profile_id = -1; + sf->sf_profile_id = -1; int sf_profile_id = 0; int sf_profile_index = 0; int sf_profile_num = 0; @@ -1041,28 +964,28 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc memset(&buffer, 0, sizeof(buffer)); snprintf(buffer, sizeof(buffer), "%u", sf_profile_id); - sf = (struct sf_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sf_table_id, buffer); - if (sf == NULL) + sf_param = (struct sf_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sf_table_id, buffer); + if (sf_param == NULL) { LOG_ERROR("%s: failed to get sf parameter of profile %d", LOG_TAG_POLICY, sf_profile_id); fixed_num_array_del_elem(array, sf_profile_id); continue; } - health_check_session_id = sf->health_check_session_id; - sf_param_free(sf); + health_check_session_id = sf_param->health_check_session_id; + sf_param_free(sf_param); - memset(sf_dst_mac, 0, 32); - if (health_check_session_get_mac(health_check_session_id, sf_dst_mac) == 0) + memset(sf->sf_dst_mac, 0, 32); + if (health_check_session_get_mac(health_check_session_id, sf->sf_dst_mac) == 0) { - __atomic_fetch_add(&g_metrics->sf_active_times, 1, __ATOMIC_RELAXED); + ATOMIC_INC(&(g_metrics->sf_status.active)); - *selected_sf_profile_id = sf_profile_id; - *sf_action_reason = ACTION_FORWAED_DUE_SELECTED_AVAILABLE_SF; + sf->sf_profile_id = sf_profile_id; + sf->sf_action_reason = ACTION_FORWAED_DUE_SELECTED_SF; return SESSION_ACTION_FORWARD; } else { - __atomic_fetch_add(&g_metrics->sf_inactive_times, 1, __ATOMIC_RELAXED); + ATOMIC_INC(&(g_metrics->sf_status.inactive)); if (sff_param->sff_exception.fail_action == FAILURE_ACTION_RE_DISPATCH) { @@ -1071,7 +994,7 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc if (sff_param->sff_exception.health_service_func_lt > 0 && sf_profile_num < sff_param->sff_exception.health_service_func_lt) { - *sf_action_reason = ACTION_BYPASS_DUE_HEALTH_SF_LIMIT; + sf->sf_action_reason = ACTION_BYPASS_DUE_HEALTH_SF_LIMIT; return SESSION_ACTION_BYPASS; } else @@ -1080,12 +1003,12 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc { if (sff_param->sff_exception.unavail_action == UNAVAILABLE_ACTION_BYPASSS) { - *sf_action_reason = ACTION_BYPASS_DUE_UNAVAILABLE_ACTION; + sf->sf_action_reason = ACTION_BYPASS_DUE_UNAVAILABLE_ACTION; return SESSION_ACTION_BYPASS; } else { - *sf_action_reason = ACTION_BLOCK_DUE_UNAVAILABLE_ACTION; + sf->sf_action_reason = ACTION_BLOCK_DUE_UNAVAILABLE_ACTION; return SESSION_ACTION_BLOCK; } } @@ -1097,20 +1020,20 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc } else if (sff_param->sff_exception.fail_action == FAILURE_ACTION_BYPASS) { - *selected_sf_profile_id = sf_profile_id; - *sf_action_reason = ACTION_BYPASS_DUE_FAILURE_ACTION; + sf->sf_profile_id = sf_profile_id; + sf->sf_action_reason = ACTION_BYPASS_DUE_FAILURE_ACTION; return SESSION_ACTION_BYPASS; } else if (sff_param->sff_exception.fail_action == FAILURE_ACTION_BLOCK) { - *selected_sf_profile_id = sf_profile_id; - *sf_action_reason = ACTION_BLOCK_DUE_FAILURE_ACTION; + sf->sf_profile_id = sf_profile_id; + sf->sf_action_reason = ACTION_BLOCK_DUE_FAILURE_ACTION; return SESSION_ACTION_BLOCK; } } }; - *sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY; + sf->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY; return SESSION_ACTION_BYPASS; } @@ -1130,10 +1053,228 @@ static void selected_sf_init(struct selected_sf *item) } } +static void connectivity_copy(struct connectivity *dst, struct connectivity *src) +{ + if (dst && src) + { + dst->method = src->method; + dst->int_vlan_tag = src->int_vlan_tag; + dst->ext_vlan_tag = src->ext_vlan_tag; + memcpy(dst->dest_ip, src->dest_ip, sizeof(dst->dest_ip)); + } +} + /****************************************************************************** * Public API ******************************************************************************/ +const char *traffic_type_to_string(enum traffic_type traffic_type) +{ + switch (traffic_type) + { + case TRAFFIC_TYPE_NONE: + return "none"; + case TRAFFIC_TYPE_RAW: + return "raw"; + case TRAFFIC_TYPE_DECRYPTED: + return "decrypted"; + default: + return "unknown"; + } +} + +const char *forward_type_to_string(enum forward_type forward_type) +{ + switch (forward_type) + { + case FORWARD_TYPE_NONE: + return "none"; + case FORWARD_TYPE_STEERING: + return "steering"; + case FORWARD_TYPE_MIRRORING: + return "mirroring"; + default: + return "unknown"; + } +} + +const char *session_action_to_string(enum session_action session_action) +{ + switch (session_action) + { + case SESSION_ACTION_BYPASS: + return "bypass"; + case SESSION_ACTION_FORWARD: + return "forward"; + case SESSION_ACTION_BLOCK: + return "block"; + default: + return "unknown"; + } +} + +const char *action_reason_to_string(enum action_reason action_reason) +{ + switch (action_reason) + { + case ACTION_BYPASS_DUE_DEFAULT: + return "bypass_due_default"; + case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT: + return "bypass_due_health_sf_limit"; + case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION: + return "bypass_due_unavailable_action"; + case ACTION_BYPASS_DUE_FAILURE_ACTION: + return "bypass_due_failure_action"; + case ACTION_BYPASS_DUE_INVALID_POLICY: + return "bypass_due_invalid_policy"; + case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION: + return "block_due_unavailable_action"; + case ACTION_BLOCK_DUE_FAILURE_ACTION: + return "block_due_failure_action"; + case ACTION_FORWAED_DUE_SELECTED_SF: + return "forward_due_selected_sf"; + default: + return "unknown"; + } +} + +const char *package_method_to_string(enum package_method package_method) +{ + switch (package_method) + { + case PACKAGE_METHOD_NONE: + return "none"; + case PACKAGE_METHOD_LAYER2_SWITCH: + return "layer2_switch"; + case PACKAGE_METHOD_LAYER3_SWITCH: + return "layer3_switch"; + case PACKAGE_METHOD_VXLAN_G: + return "vxlan_g"; + default: + return "unknown"; + } +} + +// return NULL : error +// return !NULL : success +struct selected_chaining *selected_chaining_create(int chaining_size, uint64_t session_id, char *session_addr) +{ + struct selected_chaining *chaining = (struct selected_chaining *)calloc(1, sizeof(struct selected_chaining)); + assert(chaining); + chaining->chaining_used = 0; + chaining->chaining_size = chaining_size; + chaining->chaining = (struct selected_sf *)calloc(chaining->chaining_size, sizeof(struct selected_sf)); + assert(chaining->chaining); + + for (int i = 0; i < chaining->chaining_size; i++) + { + struct selected_sf *item = &(chaining->chaining[i]); + selected_sf_init(item); + } + chaining->session_id = session_id; + chaining->session_addr = session_addr; + + return chaining; +} + +void selected_chaining_destory(struct selected_chaining *chaining) +{ + if (chaining) + { + if (chaining->chaining) + { + free(chaining->chaining); + chaining->chaining = NULL; + } + free(chaining); + chaining = NULL; + } +} + +void selected_chaining_dump(struct selected_chaining *chaining) +{ + if (chaining == NULL) + { + LOG_DEBUG("%s: selected_chaining: NULL", LOG_TAG_POLICY); + return; + } + + LOG_DEBUG("%s: session %lu %s selected_chaining->chaining_size : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, chaining->chaining_size); + LOG_DEBUG("%s: session %lu %s selected_chaining->chaining_used : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, chaining->chaining_used); + + for (int i = 0; i < chaining->chaining_used; i++) + { + struct selected_sf *node = &(chaining->chaining[i]); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->policy_id : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->policy_id); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->traffic_type : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, traffic_type_to_string(node->traffic_type)); + // sff + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sff_profile_id : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sff_profile_id); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sff_forward_type : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, forward_type_to_string(node->sff_forward_type)); + // sf + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_profile_id : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_profile_id); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_need_skip : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_need_skip); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_action : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, session_action_to_string(node->sf_action)); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_action_reason : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, action_reason_to_string(node->sf_action_reason)); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->package_method : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, package_method_to_string(node->sf_connectivity.method)); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->int_vlan_tag : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_connectivity.int_vlan_tag); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->ext_vlan_tag : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_connectivity.ext_vlan_tag); + LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->dest_ip : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_connectivity.dest_ip); + } +} + +void selected_chaining_bref(struct selected_chaining *chaining) +{ + if (chaining == NULL) + { + return; + } + + char buff[4096] = {0}; + int buff_used = 0; + int buff_size = sizeof(buff); + buff_used += snprintf(buff + buff_used, buff_size - buff_used, "chaining_size:%d, chaining_used:%d, {", chaining->chaining_size, chaining->chaining_used); + for (int i = 0; i < chaining->chaining_used; i++) + { + struct selected_sf *node = &(chaining->chaining[i]); + if (buff_size - buff_used > 0) + { + if (i != 0) + { + buff_used += snprintf(buff + buff_used, buff_size - buff_used, ","); + } + buff_used += snprintf(buff + buff_used, buff_size - buff_used, + "\"node[%d]\":{\"skip\":%d,\"policy_id\":%d,\"sff_profile_id\":%d,\"sf_profile_id\":%d,\"traffic_type\":\"%s\",\"sff_forward_type\":\"%s\",\"sf_action\":\"%s\",\"reason\":\"%s\"}", + i, node->sf_need_skip, node->policy_id, node->sff_profile_id, node->sf_profile_id, + traffic_type_to_string(node->traffic_type), forward_type_to_string(node->sff_forward_type), session_action_to_string(node->sf_action), action_reason_to_string(node->sf_action_reason)); + } + } + LOG_INFO("%s: session %lu %s selected_chaining_bref: %s}", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, buff); +} + +void selected_chaining_uniq(struct selected_chaining *chaining) +{ + if (chaining == NULL) + { + return; + } + + // Selected Service Chaining Before Unique : [1,2,3,1,2] + // Selected Service Chaining After Unique : [1,2,3] + for (int i = 0; i < chaining->chaining_used; i++) + { + struct selected_sf *node_i = &(chaining->chaining[i]); + for (int j = 0; j < i; j++) + { + struct selected_sf *node_j = &(chaining->chaining[j]); + if (node_i->sf_profile_id == node_j->sf_profile_id) + { + node_i->sf_need_skip = 1; + break; + } + } + } +} + // return NULL : error // return !NULL : success struct policy_enforcer *policy_enforcer_create(const char *instance, const char *profile, int thread_num, void *logger) @@ -1261,15 +1402,11 @@ void policy_enforcer_destory(struct policy_enforcer *enforcer) } } -int policy_enforce_max_chaining_size(struct policy_enforcer *enforcer) -{ - return enforcer->config.max_chaining_size; -} - // return 0 : success // return -1 : error int policy_enforcer_register(struct policy_enforcer *enforcer) { + LOG_INFO("%s: register policy callback ...", LOG_TAG_POLICY); enforcer->compile_table_id = Maat_table_register(enforcer->maat, "SERVICE_CHAINING_COMPILE"); if (enforcer->compile_table_id < 0) { @@ -1320,117 +1457,43 @@ int policy_enforcer_register(struct policy_enforcer *enforcer) LOG_ERROR("%s: register SERVICE_FUNCTION_PROFILE plugin extension callbacks failed", LOG_TAG_POLICY); return -1; } + LOG_INFO("%s: register policy callback success", LOG_TAG_POLICY); return 0; } -// return NULL : error -// return !NULL : success -struct selected_chaining *selected_chaining_create(int chaining_size) +int policy_enforce_chaining_size(struct policy_enforcer *enforcer) { - struct selected_chaining *chaining = (struct selected_chaining *)calloc(1, sizeof(struct selected_chaining)); - assert(chaining); - chaining->chaining_used = 0; - chaining->chaining_size = chaining_size; - chaining->chaining = (struct selected_sf *)calloc(chaining->chaining_size, sizeof(struct selected_sf)); - assert(chaining->chaining); - - for (int i = 0; i < chaining->chaining_size; i++) - { - struct selected_sf *item = &(chaining->chaining[i]); - selected_sf_init(item); - } - - return chaining; + return enforcer->config.max_chaining_size; } -void selected_chaining_destory(struct selected_chaining *chaining) +void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct raw_pkt_parser *parser, int policy_id, int dir_is_i2e) { - if (chaining) - { - if (chaining->chaining) - { - free(chaining->chaining); - chaining->chaining = NULL; - } - free(chaining); - chaining = NULL; - } -} - -void selected_chaining_dump(struct selected_chaining *chaining) -{ - if (chaining == NULL) - { - LOG_DEBUG("%s: selected_chaining: NULL", LOG_TAG_POLICY); - return; - } - - LOG_DEBUG("%s: selected_chaining->chaining_size : %d", LOG_TAG_POLICY, chaining->chaining_size); - LOG_DEBUG("%s: selected_chaining->chaining_used : %d", LOG_TAG_POLICY, chaining->chaining_used); - - for (int i = 0; i < chaining->chaining_used; i++) - { - struct selected_sf *node = &(chaining->chaining[i]); - LOG_DEBUG("%s: selected_chaining->node[%d]->policy_id : %d", LOG_TAG_POLICY, i, node->policy_id); - LOG_DEBUG("%s: selected_chaining->node[%d]->traffic_type : %s", LOG_TAG_POLICY, i, traffic_type_to_string(node->traffic_type)); - // sff - LOG_DEBUG("%s: selected_chaining->node[%d]->sff_profile_id : %d", LOG_TAG_POLICY, i, node->sff_profile_id); - LOG_DEBUG("%s: selected_chaining->node[%d]->sff_forward_type : %s", LOG_TAG_POLICY, i, forward_type_to_string(node->sff_forward_type)); - // sf - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_profile_id : %d", LOG_TAG_POLICY, i, node->sf_profile_id); - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_need_skip : %d", LOG_TAG_POLICY, i, node->sf_need_skip); - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_action : %s", LOG_TAG_POLICY, i, session_action_to_string(node->sf_action)); - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_action_reason : %s", LOG_TAG_POLICY, i, session_action_reason_to_string(node->sf_action_reason)); - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->package_method : %s", LOG_TAG_POLICY, i, package_method_to_string(node->sf_connectivity.method)); - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->int_vlan_tag : %d", LOG_TAG_POLICY, i, node->sf_connectivity.int_vlan_tag); - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->ext_vlan_tag : %d", LOG_TAG_POLICY, i, node->sf_connectivity.ext_vlan_tag); - LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->dest_ip : %s", LOG_TAG_POLICY, i, node->sf_connectivity.dest_ip); - } -} - -void selected_chaining_bref(struct selected_chaining *chaining) -{ - if (chaining == NULL) - { - return; - } - - char buff[4096] = {0}; - int buff_used = 0; - int buff_size = sizeof(buff); - buff_used += snprintf(buff + buff_used, buff_size - buff_used, "chaining_size:%d, chaining_used:%d, {", chaining->chaining_size, chaining->chaining_used); - for (int i = 0; i < chaining->chaining_used; i++) - { - struct selected_sf *node = &(chaining->chaining[i]); - if (buff_size - buff_used > 0) - { - buff_used += snprintf(buff + buff_used, buff_size - buff_used, "\"node[%d]\":{\"skip\":%d,\"reason\":\"%s\",\"policy_id\":%d,\"sff_profile_id\":%d,\"sf_profile_id\":%d,\"sff_forward_type\":\"%s\"}, ", i, node->sf_need_skip, session_action_reason_to_string(node->sf_action_reason), node->policy_id, node->sff_profile_id, node->sf_profile_id, forward_type_to_string(node->sff_forward_type)); - } - } - LOG_DEBUG("%s: selected_chaining_bref: %s}", LOG_TAG_POLICY, buff); -} - -void policy_enforce_select_chaining(struct selected_chaining *chaining, struct policy_enforcer *enforcer, struct raw_pkt_parser *parser, int policy_id, int dir_is_internal, struct session_ctx *s_ctx) -{ - struct thread_ctx *thread = (struct thread_ctx *)s_ctx->ref_thread_ctx; - struct global_metrics *g_metrics = thread->ref_metrics; - uint64_t hash_value = 0; char buffer[16] = {0}; struct sf_param *sf_param = NULL; struct sff_param *sff_param = NULL; struct fixed_num_array array = {0}; struct chaining_param *chaining_param = NULL; + struct selected_chaining *chaining = NULL; snprintf(buffer, sizeof(buffer), "%d", policy_id); chaining_param = (struct chaining_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->compile_table_id, buffer); if (chaining_param == NULL) { - LOG_ERROR("%s: failed to get chaining parameter of policy %d", LOG_TAG_POLICY, policy_id); + LOG_ERROR("%s: session %lu %s failed to get chaining parameter of policy %d", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, policy_id); return; } - LOG_DEBUG("%s: enforce chaining policy %d", LOG_TAG_POLICY, policy_id); + + if (chaining_param->traffic_type == TRAFFIC_TYPE_RAW) + { + chaining = chainings->chaining_raw; + } + else + { + chaining = chainings->chaining_decrypted; + } + LOG_INFO("%s: session %lu %s enforce %s chaining policy %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, traffic_type_to_string(chaining_param->traffic_type), policy_id); for (int i = 0; i < chaining_param->sff_profile_ids_num && chaining->chaining_used < chaining->chaining_size; i++) { @@ -1447,19 +1510,18 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p sff_param = (struct sff_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sff_table_id, buffer); if (sff_param == NULL) { - LOG_ERROR("%s: failed to get sff parameter of profile %d, bypass current sff !!!", LOG_TAG_POLICY, item->sff_profile_id); + LOG_ERROR("%s: session %lu %s failed to get sff parameter of profile %d, bypass current sff !!!", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, item->sff_profile_id); item->sf_action = SESSION_ACTION_BYPASS; item->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY; chaining->chaining_used++; continue; } item->sff_forward_type = sff_param->sff_forward_type; - LOG_DEBUG("%s: chaining policy %d -> sff_profile %d sf_profile_ids_num %d (before filter nearby and active)", LOG_TAG_POLICY, policy_id, item->sff_profile_id, sff_param->sf_profile_ids_num); memset(&array, 0, sizeof(array)); fixed_num_array_init(&array); - select_sf_by_nearby_and_active(enforcer, sff_param, &array); - LOG_DEBUG("%s: chaining policy %d -> sff_profile %d sf_profile_ids_num %d (after filter nearby and active)", LOG_TAG_POLICY, policy_id, item->sff_profile_id, fixed_num_array_count_elem(&array)); + select_sf_by_nearby_and_adminstatus(enforcer, sff_param, &array); + LOG_DEBUG("%s: session %lu %s select sf from chaining policy %d sff_profile %d, sf_profile_num (before filter: %d -> filter nearby/admin_status: %d)", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, policy_id, item->sff_profile_id, sff_param->sf_profile_ids_num, fixed_num_array_count_elem(&array)); if (fixed_num_array_count_elem(&array) == 0) { switch (sff_param->sff_exception.fail_action) @@ -1485,15 +1547,14 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p } break; } - LOG_DEBUG("%s: chaining policy %d -> sff_profile %d, no sf available after filtering by 'nearby & active', %s", LOG_TAG_POLICY, policy_id, item->sff_profile_id, session_action_reason_to_string(item->sf_action_reason)); + LOG_DEBUG("%s: session %lu %s select sf frome chaining policy %d sff_profile %d, no sf available after filtering by 'nearby & admin_status', %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, policy_id, item->sff_profile_id, action_reason_to_string(item->sf_action_reason)); chaining->chaining_used++; sff_param_free(sff_param); continue; } - hash_value = raw_packet_parser_get_hash_value(parser, sff_param->sff_ldbc.method, dir_is_internal); - item->sf_action = select_sf_by_ldbc(hash_value, enforcer, sff_param, &array, &(item->sf_profile_id), &(item->sf_action_reason), item->sf_dst_mac, s_ctx); - LOG_DEBUG("%s: chaining policy %d -> sff_profile %d sf_profile_ids_num %d (after filter ldbc)", LOG_TAG_POLICY, policy_id, item->sff_profile_id, fixed_num_array_count_elem(&array)); + hash_value = raw_packet_parser_get_hash_value(parser, sff_param->sff_ldbc.method, dir_is_i2e); + item->sf_action = select_sf_by_ldbc(enforcer, s_ctx, sff_param, item, &array, hash_value); if (item->sf_action != SESSION_ACTION_FORWARD) { chaining->chaining_used++; @@ -1506,7 +1567,7 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p sf_param = (struct sf_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sf_table_id, buffer); if (sf_param == NULL) { - LOG_ERROR("%s: failed to get sf parameter of selected profile %d, bypass current sff !!!", LOG_TAG_POLICY, item->sf_profile_id); + LOG_ERROR("%s: session %lu %s failed to get sf parameter of profile %d, bypass current sff !!!", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, item->sf_profile_id); item->sf_action = SESSION_ACTION_BYPASS; item->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY; chaining->chaining_used++; @@ -1514,33 +1575,14 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p continue; } - item->sf_connectivity.method = sf_param->sf_connectivity.method; - item->sf_connectivity.int_vlan_tag = sf_param->sf_connectivity.int_vlan_tag; - item->sf_connectivity.ext_vlan_tag = sf_param->sf_connectivity.ext_vlan_tag; - memcpy(item->sf_connectivity.dest_ip, sf_param->sf_connectivity.dest_ip, strlen(sf_param->sf_connectivity.dest_ip)); + connectivity_copy(&item->sf_connectivity, &sf_param->sf_connectivity); memcpy(item->sf_dst_ip, sf_param->sf_connectivity.dest_ip, strlen(sf_param->sf_connectivity.dest_ip)); - chaining->chaining_used++; sf_param_free(sf_param); sff_param_free(sff_param); } - // Selected Service Chaining Before Unique : [1,2,3,1,2] - // Selected Service Chaining After Unique : [1,2,3] - for (int i = 0; i < chaining->chaining_used; i++) - { - struct selected_sf *node_i = &(chaining->chaining[i]); - for (int j = 0; j < i; j++) - { - struct selected_sf *node_j = &(chaining->chaining[j]); - if (node_i->sf_profile_id == node_j->sf_profile_id) - { - node_i->sf_need_skip = 1; - break; - } - } - } - + selected_chaining_uniq(chaining); chaining_param_free(chaining_param); } diff --git a/platform/src/sce.cpp b/platform/src/sce.cpp index 1974cc5..be62dbe 100644 --- a/platform/src/sce.cpp +++ b/platform/src/sce.cpp @@ -6,107 +6,194 @@ #include "global_metrics.h" /****************************************************************************** - * session_ctx + * Struct Metadata ******************************************************************************/ -struct session_ctx *session_ctx_new() +struct metadata *metadata_new() { - struct session_ctx *ctx = (struct session_ctx *)calloc(1, sizeof(struct session_ctx)); - assert(ctx != NULL); - return ctx; + struct metadata *meta = (struct metadata *)calloc(1, sizeof(struct metadata)); + + return meta; } -void session_ctx_free(struct session_ctx *ctx) +int metadata_is_empty(struct metadata *meta) { - if (ctx) + if (meta->write_ref == 0) { - if (ctx->first_ctrl_pkt.addr_string) + return 1; + } + else + { + return 0; + } +} + +void metadata_deep_copy(struct metadata *dst, struct metadata *src) +{ + dst->write_ref++; + dst->session_id = src->session_id; + dst->raw_data = strndup(src->raw_data, src->raw_len); + dst->raw_len = src->raw_len; + dst->l7offset = src->l7offset; + dst->is_e2i_dir = src->is_e2i_dir; + dst->is_ctrl_pkt = src->is_ctrl_pkt; + dst->is_decrypted = src->is_decrypted; + + sids_copy(&dst->sids, &src->sids); + route_ctx_copy(&dst->route_ctx, &src->route_ctx); +} + +void metadata_shadow_copy(struct metadata *dst, struct metadata *src) +{ + dst->write_ref++; + dst->session_id = src->session_id; + dst->raw_data = src->raw_data; + dst->raw_len = src->raw_len; + dst->l7offset = src->l7offset; + dst->is_e2i_dir = src->is_e2i_dir; + dst->is_ctrl_pkt = src->is_ctrl_pkt; + dst->is_decrypted = src->is_decrypted; + + sids_copy(&dst->sids, &src->sids); + route_ctx_copy(&dst->route_ctx, &src->route_ctx); +} + +void metadata_free(struct metadata *meta) +{ + if (meta) + { + if (meta->raw_data) { - free(ctx->first_ctrl_pkt.addr_string); - ctx->first_ctrl_pkt.addr_string = NULL; + free(meta->raw_data); + meta->raw_data = NULL; } - if (ctx->first_ctrl_pkt.header_data) - { - free(ctx->first_ctrl_pkt.header_data); - ctx->first_ctrl_pkt.header_data = NULL; - } - - if (ctx->chaining) - { - selected_chaining_destory(ctx->chaining); - ctx->chaining = NULL; - } - - free(ctx); - ctx = 0; + free(meta); + meta = NULL; } } /****************************************************************************** - * sce_ctx + * Struct Session Ctx + ******************************************************************************/ + +struct session_ctx *session_ctx_new() +{ + struct session_ctx *session_ctx = (struct session_ctx *)calloc(1, sizeof(struct session_ctx)); + assert(session_ctx != NULL); + + fixed_num_array_init(&session_ctx->policy_ids); + + session_ctx->raw_meta_i2e = metadata_new(); + session_ctx->raw_meta_e2i = metadata_new(); + session_ctx->ctrl_meta = metadata_new(); + + return session_ctx; +} + +void session_ctx_free(struct session_ctx *session_ctx) +{ + if (session_ctx) + { + if (session_ctx->raw_meta_i2e) + { + metadata_free(session_ctx->raw_meta_i2e); + session_ctx->raw_meta_i2e = NULL; + } + + if (session_ctx->raw_meta_e2i) + { + metadata_free(session_ctx->raw_meta_e2i); + session_ctx->raw_meta_e2i = NULL; + } + + if (session_ctx->ctrl_meta) + { + metadata_free(session_ctx->ctrl_meta); + session_ctx->ctrl_meta = NULL; + } + + if (session_ctx->chainings.chaining_raw) + { + selected_chaining_destory(session_ctx->chainings.chaining_raw); + session_ctx->chainings.chaining_raw = NULL; + } + + if (session_ctx->chainings.chaining_decrypted) + { + selected_chaining_destory(session_ctx->chainings.chaining_decrypted); + session_ctx->chainings.chaining_decrypted = NULL; + } + + free(session_ctx); + session_ctx = 0; + } +} + +/****************************************************************************** + * Struct SCE Ctx ******************************************************************************/ struct sce_ctx *sce_ctx_create(const char *profile) { - struct sce_ctx *ctx = (struct sce_ctx *)calloc(1, sizeof(struct sce_ctx)); + struct sce_ctx *sce_ctx = (struct sce_ctx *)calloc(1, sizeof(struct sce_ctx)); - MESA_load_profile_int_def(profile, "system", "enable_debug", (int *)&(ctx->enable_debug), 0); - MESA_load_profile_int_def(profile, "system", "firewall_sids", (int *)&(ctx->firewall_sids), 1001); - MESA_load_profile_int_def(profile, "system", "nr_worker_threads", (int *)&(ctx->nr_worker_threads), 8); - MESA_load_profile_uint_range(profile, "system", "cpu_affinity_mask", MAX_THREAD_NUM, (unsigned int *)ctx->cpu_affinity_mask); - MESA_load_profile_int_def(profile, "system", "ts_update_interval_ms", (int *)&(ctx->ts_update_interval_ms), 1); - ctx->nr_worker_threads = MIN(ctx->nr_worker_threads, MAX_THREAD_NUM); + MESA_load_profile_int_def(profile, "system", "enable_debug", (int *)&(sce_ctx->enable_debug), 0); + MESA_load_profile_int_def(profile, "system", "enable_send_log", (int *)&(sce_ctx->enable_send_log), 0); + MESA_load_profile_int_def(profile, "system", "firewall_sids", (int *)&(sce_ctx->firewall_sids), 1001); + MESA_load_profile_int_def(profile, "system", "nr_worker_threads", (int *)&(sce_ctx->nr_worker_threads), 8); + MESA_load_profile_uint_range(profile, "system", "cpu_affinity_mask", MAX_THREAD_NUM, (unsigned int *)sce_ctx->cpu_affinity_mask); + MESA_load_profile_int_def(profile, "system", "ts_update_interval_ms", (int *)&(sce_ctx->ts_update_interval_ms), 1); - CPU_ZERO(&ctx->coremask); - for (int i = 0; i < ctx->nr_worker_threads; i++) + sce_ctx->nr_worker_threads = MIN(sce_ctx->nr_worker_threads, MAX_THREAD_NUM); + CPU_ZERO(&sce_ctx->coremask); + for (int i = 0; i < sce_ctx->nr_worker_threads; i++) { - int cpu_id = ctx->cpu_affinity_mask[i]; - CPU_SET(cpu_id, &ctx->coremask); + int cpu_id = sce_ctx->cpu_affinity_mask[i]; + CPU_SET(cpu_id, &sce_ctx->coremask); } - ctx->ts = timestamp_new(ctx->ts_update_interval_ms); - - ctx->io = packet_io_create(profile, ctx->nr_worker_threads, &ctx->coremask); - if (ctx->io == NULL) + sce_ctx->ts = timestamp_new(sce_ctx->ts_update_interval_ms); + sce_ctx->metrics = global_metrics_create(profile); + if (sce_ctx->metrics == NULL) { goto error_out; } - ctx->metrics = global_metrics_create(profile); - if (ctx->metrics == NULL) + sce_ctx->enforcer = policy_enforcer_create("SCE", profile, sce_ctx->nr_worker_threads, NULL); + if (sce_ctx->enforcer == NULL) { goto error_out; } - ctx->enforcer = policy_enforcer_create("SCE", profile, ctx->nr_worker_threads, NULL); - if (ctx->enforcer == NULL) + if (policy_enforcer_register(sce_ctx->enforcer) == -1) { goto error_out; } - if (policy_enforcer_register(ctx->enforcer) == -1) + sce_ctx->io = packet_io_create(profile, sce_ctx->nr_worker_threads, &sce_ctx->coremask); + if (sce_ctx->io == NULL) { goto error_out; } - return ctx; + return sce_ctx; error_out: - sce_ctx_destory(ctx); + sce_ctx_destory(sce_ctx); return NULL; } -void sce_ctx_destory(struct sce_ctx *ctx) +void sce_ctx_destory(struct sce_ctx *sce_ctx) { - if (ctx) + if (sce_ctx) { - policy_enforcer_destory(ctx->enforcer); - global_metrics_destory(ctx->metrics); - packet_io_destory(ctx->io); - timestamp_free(ctx->ts); + packet_io_destory(sce_ctx->io); + policy_enforcer_destory(sce_ctx->enforcer); + global_metrics_destory(sce_ctx->metrics); + timestamp_free(sce_ctx->ts); - free(ctx); - ctx = NULL; + free(sce_ctx); + sce_ctx = NULL; } } diff --git a/platform/src/sf_metrics.cpp b/platform/src/sf_metrics.cpp index 0a858d5..f78bde9 100644 --- a/platform/src/sf_metrics.cpp +++ b/platform/src/sf_metrics.cpp @@ -55,10 +55,10 @@ static void sf_metrics_parse_config(const char *profile, struct sf_metrics_confi MESA_load_profile_int_def(profile, "METRICS", "telegraf_listen_port", &(config->telegraf_listen_port), 8300); MESA_load_profile_string_def(profile, "METRICS", "telegraf_bind_address", config->telegraf_bind_address, sizeof(config->telegraf_bind_address), "127.0.0.1"); - LOG_DEBUG("%s: METRICS->enable : %d", LOG_TAG_SF_METRICS, config->enable); - LOG_DEBUG("%s: METRICS->interval_s : %d", LOG_TAG_SF_METRICS, config->interval_s); - LOG_DEBUG("%s: METRICS->telegraf_listen_port : %d", LOG_TAG_SF_METRICS, config->telegraf_listen_port); - LOG_DEBUG("%s: METRICS->telegraf_bind_address : %s", LOG_TAG_SF_METRICS, config->telegraf_bind_address); + LOG_DEBUG("%s: METRICS->enable : %d", LOG_TAG_SF_METRICS, config->enable); + LOG_DEBUG("%s: METRICS->interval_s : %d", LOG_TAG_SF_METRICS, config->interval_s); + LOG_DEBUG("%s: METRICS->telegraf_listen_port : %d", LOG_TAG_SF_METRICS, config->telegraf_listen_port); + LOG_DEBUG("%s: METRICS->telegraf_bind_address : %s", LOG_TAG_SF_METRICS, config->telegraf_bind_address); } struct sf_metrics *sf_metrics_create(const char *profile) diff --git a/platform/src/sf_status.cpp b/platform/src/sf_status.cpp index cd7069d..359caf3 100644 --- a/platform/src/sf_status.cpp +++ b/platform/src/sf_status.cpp @@ -45,10 +45,10 @@ static void sf_status_parse_config(const char *profile, struct sf_status_config MESA_load_profile_int_def(profile, "METRICS", "telegraf_listen_port", &(config->telegraf_listen_port), 8300); MESA_load_profile_string_def(profile, "METRICS", "telegraf_bind_address", config->telegraf_bind_address, sizeof(config->telegraf_bind_address), "127.0.0.1"); - LOG_DEBUG("%s: METRICS->enable : %d", LOG_TAG_SF_STATUS, config->enable); - LOG_DEBUG("%s: METRICS->interval_s : %d", LOG_TAG_SF_STATUS, config->interval_s); - LOG_DEBUG("%s: METRICS->telegraf_listen_port : %d", LOG_TAG_SF_STATUS, config->telegraf_listen_port); - LOG_DEBUG("%s: METRICS->telegraf_bind_address : %s", LOG_TAG_SF_STATUS, config->telegraf_bind_address); + LOG_DEBUG("%s: METRICS->enable : %d", LOG_TAG_SF_STATUS, config->enable); + LOG_DEBUG("%s: METRICS->interval_s : %d", LOG_TAG_SF_STATUS, config->interval_s); + LOG_DEBUG("%s: METRICS->telegraf_listen_port : %d", LOG_TAG_SF_STATUS, config->telegraf_listen_port); + LOG_DEBUG("%s: METRICS->telegraf_bind_address : %s", LOG_TAG_SF_STATUS, config->telegraf_bind_address); } void sf_status_destory(struct sf_status *handle) @@ -104,7 +104,7 @@ struct sf_status *sf_status_create(const char *profile) void sf_status_reset(struct sf_status *handle) { - if (handle->config.enable == 0) + if (handle == NULL || handle->config.enable == 0) { return; } @@ -125,7 +125,7 @@ void sf_status_reset(struct sf_status *handle) void sf_status_delete(struct sf_status *handle, int sf_profile_id) { - if (handle->config.enable == 0) + if (handle == NULL || handle->config.enable == 0) { return; } @@ -146,7 +146,7 @@ void sf_status_delete(struct sf_status *handle, int sf_profile_id) void sf_status_update(struct sf_status *handle, int sf_profile_id, int sf_status, int sf_latency) { - if (handle->config.enable == 0) + if (handle == NULL || handle->config.enable == 0) { return; } @@ -185,7 +185,7 @@ void sf_status_send(struct sf_status *handle) struct node *temp = NULL; struct node *node = NULL; - if (handle->config.enable == 0) + if (handle == NULL || handle->config.enable == 0) { return; } @@ -203,5 +203,12 @@ void sf_status_send(struct sf_status *handle) int sf_status_get_interval(struct sf_status *handle) { - return handle->config.interval_s; + if (handle == NULL) + { + return 0; + } + else + { + return handle->config.interval_s; + } } \ No newline at end of file diff --git a/platform/test/gtest_policy.cpp b/platform/test/gtest_policy.cpp index 7eced18..7e85497 100644 --- a/platform/test/gtest_policy.cpp +++ b/platform/test/gtest_policy.cpp @@ -18,7 +18,7 @@ TEST(POLICY, SELECTED_CHAINING_LIFE_CYCLE) { struct selected_chaining *chaining = NULL; - chaining = selected_chaining_create(128); + chaining = selected_chaining_create(128, 0, NULL); EXPECT_TRUE(chaining != nullptr); selected_chaining_destory(chaining); @@ -45,16 +45,22 @@ TEST(POLICY, POLICY_ENFORCER_LIFE_CYCLE) EXPECT_TRUE(enforcer != nullptr); EXPECT_TRUE(policy_enforcer_register(enforcer) == 0); - int dir_is_internal = 1; - struct selected_chaining *chaining = selected_chaining_create(64); - EXPECT_TRUE(chaining != nullptr); - policy_enforce_select_chaining(chaining, enforcer, &handler, 1, dir_is_internal, &s_ctx); - policy_enforce_select_chaining(chaining, enforcer, &handler, 2, dir_is_internal, &s_ctx); - policy_enforce_select_chaining(chaining, enforcer, &handler, 11, dir_is_internal, &s_ctx); - policy_enforce_select_chaining(chaining, enforcer, &handler, 12, dir_is_internal, &s_ctx); - selected_chaining_dump(chaining); - selected_chaining_bref(chaining); - selected_chaining_destory(chaining); + int dir_is_i2e = 1; + struct selected_chainings chainings; + chainings.chaining_raw = selected_chaining_create(64, 0, NULL); + chainings.chaining_decrypted = selected_chaining_create(64, 0, NULL); + policy_enforce_select_chainings(enforcer, &chainings, &s_ctx, &handler, 1, dir_is_i2e); + policy_enforce_select_chainings(enforcer, &chainings, &s_ctx, &handler, 2, dir_is_i2e); + policy_enforce_select_chainings(enforcer, &chainings, &s_ctx, &handler, 11, dir_is_i2e); + policy_enforce_select_chainings(enforcer, &chainings, &s_ctx, &handler, 12, dir_is_i2e); + + selected_chaining_dump(chainings.chaining_raw); + selected_chaining_bref(chainings.chaining_raw); + selected_chaining_destory(chainings.chaining_raw); + + selected_chaining_dump(chainings.chaining_decrypted); + selected_chaining_bref(chainings.chaining_decrypted); + selected_chaining_destory(chainings.chaining_decrypted); printf("Before Sleep\n"); sleep(15);