diff --git a/platform/include/sf_metrics.h b/platform/include/sf_metrics.h index 67b32ad..2eda627 100644 --- a/platform/include/sf_metrics.h +++ b/platform/include/sf_metrics.h @@ -7,13 +7,20 @@ extern "C" #endif #include -#include "uthash.h" + +struct sf_metrics_key +{ + uint64_t rule_id; + uint32_t sf_profile_id; + uint32_t sff_profile_id; + uint32_t vsys_id; +}; struct sf_metrics *sf_metrics_create(const char *profile); void sf_metrics_destory(struct sf_metrics *handle); void sf_metrics_reset(struct sf_metrics *handle); -void sf_metrics_inc(struct sf_metrics *handle, int vsys_id, uint64_t rule_id, int sff_profile_id, int sf_profile_id, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes); +void sf_metrics_inc(struct sf_metrics *handle, struct sf_metrics_key *key, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes); void sf_metrics_send(struct sf_metrics *handle); int sf_metrics_get_interval(struct sf_metrics *handle); diff --git a/platform/src/packet_io.cpp b/platform/src/packet_io.cpp index 6b8326c..abc7e2f 100644 --- a/platform/src/packet_io.cpp +++ b/platform/src/packet_io.cpp @@ -623,7 +623,12 @@ static inline void action_mirr_forward(struct session_ctx *session_ctx, marsio_b int nsend = send_packet_to_sf(session_ctx, new_buff, meta, sf, thread_ctx); throughput_metrics_inc(&(thread_metrics->data_pkt.mirr_tx), 1, raw_len); throughput_metrics_inc(&sf->tx, 1, nsend); - sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend); + struct sf_metrics_key key = {0}; + key.rule_id = sf->rule_id; + key.sff_profile_id = sf->sff_profile_id; + key.sf_profile_id = sf->sf_profile_id; + key.vsys_id = sf->rule_vsys_id; + sf_metrics_inc(thread_ctx->sf_metrics, &key, 0, 0, 1, nsend); } static inline void action_stee_bypass(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx) @@ -653,7 +658,12 @@ static inline void action_stee_forward(struct session_ctx *session_ctx, marsio_b int nsend = send_packet_to_sf(session_ctx, rx_buff, meta, sf, thread_ctx); throughput_metrics_inc(&(thread_metrics->data_pkt.stee_tx), 1, raw_len); throughput_metrics_inc(&sf->tx, 1, nsend); - sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend); + struct sf_metrics_key key = {0}; + key.rule_id = sf->rule_id; + key.sff_profile_id = sf->sff_profile_id; + key.sf_profile_id = sf->sf_profile_id; + key.vsys_id = sf->rule_vsys_id; + sf_metrics_inc(thread_ctx->sf_metrics, &key, 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) @@ -1222,7 +1232,12 @@ static void handle_inject_vxlan_packet(marsio_buff_t *rx_buff, struct thread_ctx struct selected_sf *sf = &(chaining->chaining[sf_index]); throughput_metrics_inc(&sf->rx, 1, raw_len); throughput_metrics_inc(&(thread_metrics->data_pkt.stee_rx), 1, meta.raw_len); - sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 1, raw_len, 0, 0); + struct sf_metrics_key key = {0}; + key.rule_id = sf->rule_id; + key.sff_profile_id = sf->sff_profile_id; + key.sf_profile_id = sf->sf_profile_id; + key.vsys_id = sf->rule_vsys_id; + sf_metrics_inc(thread_ctx->sf_metrics, &key, 1, raw_len, 0, 0); } marsio_buff_adj(rx_buff, raw_len - meta.raw_len); diff --git a/platform/src/sf_metrics.cpp b/platform/src/sf_metrics.cpp index 01e444f..bf278e6 100644 --- a/platform/src/sf_metrics.cpp +++ b/platform/src/sf_metrics.cpp @@ -12,17 +12,13 @@ #define SCE_SF_METRICS "service_chaining_rule_hits,vsys_id=%d,rule_id=%lu,sff_profile_id=%d,sf_profile_id=%d sent_pkts=%lu,sent_bytes=%lu,recv_pkts=%lu,recv_bytes=%lu" -struct key_tuple -{ - int vsys_id; - uint64_t rule_id; - int sff_profile_id; - int sf_profile_id; -}; +// Must be defined before including uthash.h +#define HASH_KEYCMP(a, b, len) sf_metrics_key_cmp((struct sf_metrics_key *)(a), (struct sf_metrics_key *)(b)) +#include "uthash.h" struct node { - struct key_tuple key; + struct sf_metrics_key key; uint64_t sent_pkts; uint64_t sent_bytes; uint64_t recv_pkts; @@ -31,17 +27,13 @@ struct node UT_hash_handle hh; }; -struct sf_metrics_config +struct sf_metrics { int enable; int interval_s; int telegraf_listen_port; char telegraf_bind_address[2048]; -}; -struct sf_metrics -{ - struct sf_metrics_config config; struct sockaddr_in sock_addr; int sockfd; @@ -49,38 +41,54 @@ struct sf_metrics uint64_t htable_elem_count; }; -static void sf_metrics_parse_config(const char *profile, struct sf_metrics_config *config) +static inline int sf_metrics_key_cmp(struct sf_metrics_key *a, struct sf_metrics_key *b) { - MESA_load_profile_int_def(profile, "METRICS", "enable", &(config->enable), 1); - MESA_load_profile_int_def(profile, "METRICS", "interval_s", &(config->interval_s), 1); - 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"); + if (a->sf_profile_id != b->sf_profile_id) + { + return 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); + if (a->sff_profile_id != b->sff_profile_id) + { + return 1; + } + + if (a->rule_id != b->rule_id) + { + return 1; + } + + if (a->vsys_id != b->vsys_id) + { + return 1; + } + + return 0; } struct sf_metrics *sf_metrics_create(const char *profile) { struct sf_metrics *handle = (struct sf_metrics *)calloc(1, sizeof(struct sf_metrics)); assert(handle); - sf_metrics_parse_config(profile, &(handle->config)); - if (handle->config.enable == 0) + MESA_load_profile_int_def(profile, "METRICS", "enable", &(handle->enable), 1); + MESA_load_profile_int_def(profile, "METRICS", "interval_s", &(handle->interval_s), 1); + MESA_load_profile_int_def(profile, "METRICS", "telegraf_listen_port", &(handle->telegraf_listen_port), 8300); + MESA_load_profile_string_def(profile, "METRICS", "telegraf_bind_address", handle->telegraf_bind_address, sizeof(handle->telegraf_bind_address), "127.0.0.1"); + + if (handle->enable == 0) { return handle; } handle->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); handle->sock_addr.sin_family = AF_INET; - handle->sock_addr.sin_port = htons(handle->config.telegraf_listen_port); - handle->sock_addr.sin_addr.s_addr = inet_addr(handle->config.telegraf_bind_address); + handle->sock_addr.sin_port = htons(handle->telegraf_listen_port); + handle->sock_addr.sin_addr.s_addr = inet_addr(handle->telegraf_bind_address); handle->htable_elem_count = 0; if (handle->sockfd == -1) { - LOG_ERROR("%s: failed to create udp sockfd %s:%d, errno: %d, %s", LOG_TAG_SF_METRICS, handle->config.telegraf_bind_address, handle->config.telegraf_listen_port, errno, strerror(errno)); + LOG_ERROR("%s: failed to create udp sockfd %s:%d, errno: %d, %s", LOG_TAG_SF_METRICS, handle->telegraf_bind_address, handle->telegraf_listen_port, errno, strerror(errno)); sf_metrics_destory(handle); return NULL; } @@ -121,7 +129,7 @@ void sf_metrics_reset(struct sf_metrics *handle) return; } - if (handle->config.enable == 0) + if (handle->enable == 0) { return; } @@ -138,22 +146,15 @@ void sf_metrics_reset(struct sf_metrics *handle) } } -void sf_metrics_inc(struct sf_metrics *handle, int vsys_id, uint64_t rule_id, int sff_profile_id, int sf_profile_id, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes) +void sf_metrics_inc(struct sf_metrics *handle, struct sf_metrics_key *key, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes) { - if (handle->config.enable == 0) + if (handle->enable == 0) { return; } - struct key_tuple key; - memset(&key, 0, sizeof(struct key_tuple)); - key.vsys_id = vsys_id; - key.rule_id = rule_id; - key.sff_profile_id = sff_profile_id; - key.sf_profile_id = sf_profile_id; - struct node *temp = NULL; - HASH_FIND(hh, handle->htable, &key, sizeof(struct key_tuple), temp); + HASH_FIND(hh, handle->htable, key, sizeof(struct sf_metrics_key), temp); if (temp) { temp->recv_pkts += rx_pkts; @@ -164,16 +165,16 @@ void sf_metrics_inc(struct sf_metrics *handle, int vsys_id, uint64_t rule_id, in else { temp = (struct node *)calloc(1, sizeof(struct node)); - temp->key.vsys_id = vsys_id; - temp->key.rule_id = rule_id; - temp->key.sff_profile_id = sff_profile_id; - temp->key.sf_profile_id = sf_profile_id; + temp->key.vsys_id = key->vsys_id; + temp->key.rule_id = key->rule_id; + temp->key.sff_profile_id = key->sff_profile_id; + temp->key.sf_profile_id = key->sf_profile_id; temp->recv_pkts = rx_pkts; temp->recv_bytes = rx_bytes; temp->sent_pkts = tx_pkts; temp->sent_bytes = tx_bytes; - HASH_ADD(hh, handle->htable, key, sizeof(struct key_tuple), temp); + HASH_ADD(hh, handle->htable, key, sizeof(struct sf_metrics_key), temp); } } @@ -186,7 +187,7 @@ void sf_metrics_send(struct sf_metrics *handle) struct node *temp = NULL; struct node *node = NULL; - if (handle->config.enable == 0) + if (handle->enable == 0) { return; } @@ -214,5 +215,5 @@ void sf_metrics_send(struct sf_metrics *handle) int sf_metrics_get_interval(struct sf_metrics *handle) { - return handle->config.interval_s; + return handle->interval_s; } \ No newline at end of file diff --git a/platform/test/gtest_sf_metrics.cpp b/platform/test/gtest_sf_metrics.cpp index 7725e84..c9dc998 100644 --- a/platform/test/gtest_sf_metrics.cpp +++ b/platform/test/gtest_sf_metrics.cpp @@ -6,7 +6,21 @@ TEST(SF_METRICS, TEST) { struct sf_metrics *metrics = sf_metrics_create("./test_resource/sce.conf"); EXPECT_TRUE(sf_metrics_get_interval(metrics) == 1); - sf_metrics_inc(metrics, 1, 1, 2, 3, 4, 5, 6, 7); + + struct sf_metrics_key key1 = {0}; + key1.rule_id = 1; + key1.sff_profile_id = 2; + key1.sf_profile_id = 3; + key1.vsys_id = 4; + sf_metrics_inc(metrics, &key1, 4, 5, 6, 7); + + struct sf_metrics_key key2 = {0}; + key2.rule_id = 1; + key2.sff_profile_id = 2; + key2.sf_profile_id = 3; + key2.vsys_id = 4; + sf_metrics_inc(metrics, &key2, 4, 5, 6, 7); + sf_metrics_send(metrics); sf_metrics_destory(metrics); }