diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 09c6baf..01d72b0 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(common src/addr_tuple4.cpp src/session_table.cpp src/raw_packet.cpp src/bfd.cpp src/utils.cpp) +add_library(common src/addr_tuple4.cpp src/session_table.cpp src/raw_packet.cpp src/ctrl_packet.cpp src/bfd.cpp src/utils.cpp src/g_vxlan.cpp) target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) diff --git a/common/include/ctrl_packet.h b/common/include/ctrl_packet.h new file mode 100644 index 0000000..03f60da --- /dev/null +++ b/common/include/ctrl_packet.h @@ -0,0 +1,38 @@ +#ifndef _CTRL_PACKET_H +#define _CTRL_PACKET_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include + +enum session_state +{ + SESSION_STATE_OPENING = 1, + SESSION_STATE_CLONING = 2, + SESSION_STATE_ACTIVE = 3, + SESSION_STATE_RESETALL = 4, +}; + +struct ctrl_pkt_parser +{ + char tsync[4]; + uint64_t session_id; + enum session_state state; + int policy_ids[32]; + int policy_id_num; +}; + +void ctrl_packet_parser_init(struct ctrl_pkt_parser *handler); + +// return 0 : success +// return -1 : error +int ctrl_packet_parser_parse(struct ctrl_pkt_parser *handler, const void *data, size_t length); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/common/include/g_vxlan.h b/common/include/g_vxlan.h new file mode 100644 index 0000000..91a3df7 --- /dev/null +++ b/common/include/g_vxlan.h @@ -0,0 +1,52 @@ +#ifndef _G_VXLAN_H +#define _G_VXLAN_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +struct g_vxlan +{ + unsigned char flags; + unsigned char reserved[3]; + + // VNI 3 Bytes + unsigned char vlan_id_half_high; + + unsigned char link_layer_type : 4; // 二层报文封装格式 + unsigned char vlan_id_half_low : 4; + + unsigned int dir_is_e2i : 1; + unsigned int traffic_is_decrypted : 1; + unsigned int chain_index : 5; // max value 32 + unsigned int online_test : 1; + + // Reserved 1 Bytes + unsigned int r7 : 1; + unsigned int r6 : 1; + unsigned int r5 : 1; + unsigned int r4 : 1; + unsigned int vni_flag : 1; + unsigned int r2 : 1; + unsigned int r1 : 1; + unsigned int r0 : 1; +} __attribute__((__packed__)); + +void g_vxlan_set_packet_dir(struct g_vxlan *hdr, int dir_is_e2i); +void g_vxlan_set_chain_index(struct g_vxlan *hdr, int chain_index); +void g_vxlan_set_traffic_type(struct g_vxlan *hdr, int traffic_is_decrypted); + +int g_vxlan_get_packet_dir(struct g_vxlan *hdr); +int g_vxlan_get_chain_index(struct g_vxlan *hdr); +int g_vxlan_get_traffic_type(struct g_vxlan *hdr); + +// return 0 : success +// return -1 : error +int g_vxlan_decode(struct g_vxlan **g_vxlan_hd, const char *raw_data, int raw_len); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/common/include/raw_packet.h b/common/include/raw_packet.h index 886a30a..7943ed8 100644 --- a/common/include/raw_packet.h +++ b/common/include/raw_packet.h @@ -11,35 +11,35 @@ extern "C" enum layer_type { // 数据链路层 - LAYER_TYPE_ETHER = 1 << 0, - LAYER_TYPE_PPP = 1 << 1, - LAYER_TYPE_HDLC = 1 << 2, - LAYER_TYPE_L2 = (LAYER_TYPE_ETHER | LAYER_TYPE_PPP | LAYER_TYPE_HDLC), + LAYER_TYPE_ETHER = 1 << 0, + LAYER_TYPE_PPP = 1 << 1, + LAYER_TYPE_HDLC = 1 << 2, + LAYER_TYPE_L2 = (LAYER_TYPE_ETHER | LAYER_TYPE_PPP | LAYER_TYPE_HDLC), // 数据链路层 -- 隧道 - LAYER_TYPE_VLAN = 1 << 3, - LAYER_TYPE_PPPOE = 1 << 4, - LAYER_TYPE_MPLS = 1 << 5, - LAYER_TYPE_L2_TUN = (LAYER_TYPE_VLAN | LAYER_TYPE_PPPOE | LAYER_TYPE_MPLS), + LAYER_TYPE_VLAN = 1 << 3, + LAYER_TYPE_PPPOE = 1 << 4, + LAYER_TYPE_MPLS = 1 << 5, + LAYER_TYPE_L2_TUN = (LAYER_TYPE_VLAN | LAYER_TYPE_PPPOE | LAYER_TYPE_MPLS), // 网络层 - LAYER_TYPE_IPV4 = 1 << 6, - LAYER_TYPE_IPV6 = 1 << 7, - LAYER_TYPE_L3 = (LAYER_TYPE_IPV4 | LAYER_TYPE_IPV6), + LAYER_TYPE_IPV4 = 1 << 6, + LAYER_TYPE_IPV6 = 1 << 7, + LAYER_TYPE_L3 = (LAYER_TYPE_IPV4 | LAYER_TYPE_IPV6), // 网络层 -- 隧道 // 传输层 - LAYER_TYPE_UDP = 1 << 8, - LAYER_TYPE_TCP = 1 << 9, - LAYER_TYPE_L4 = (LAYER_TYPE_UDP | LAYER_TYPE_TCP), + LAYER_TYPE_UDP = 1 << 8, + LAYER_TYPE_TCP = 1 << 9, + LAYER_TYPE_L4 = (LAYER_TYPE_UDP | LAYER_TYPE_TCP), // 传输层 -- 隧道 LAYER_TYPE_G_VXLAN = 1 << 10, LAYER_TYPE_GTPV1_U = 1 << 11, // ALL - LAYER_TYPE_ALL = (LAYER_TYPE_L2 | LAYER_TYPE_L2_TUN | LAYER_TYPE_L3 | LAYER_TYPE_L4 | LAYER_TYPE_G_VXLAN | LAYER_TYPE_GTPV1_U), + LAYER_TYPE_ALL = (LAYER_TYPE_L2 | LAYER_TYPE_L2_TUN | LAYER_TYPE_L3 | LAYER_TYPE_L4 | LAYER_TYPE_G_VXLAN | LAYER_TYPE_GTPV1_U), // UNKNOWN LAYER_TYPE_UNKNOWN, @@ -47,30 +47,36 @@ enum layer_type enum ldbc_method { - LDBC_METHOD_HASH_INT_IP = 1, - LDBC_METHOD_HASH_EXT_IP = 2, - LDBC_METHOD_HASH_INT_IP_AND_EXT_IP = 3, - LDBC_METHOD_HASH_INNERMOST_INT_IP = 4, + LDBC_METHOD_HASH_INT_IP = 1, + LDBC_METHOD_HASH_EXT_IP = 2, + LDBC_METHOD_HASH_INT_IP_AND_EXT_IP = 3, + LDBC_METHOD_HASH_INNERMOST_INT_IP = 4, LDBC_METHOD_HASH_INNERMOST_EXT_IP = 5, }; -enum parse_status +struct layer_result { - PARSE_STATUS_CONTINUE, - PARSE_STATUS_STOP + uint16_t offset; + enum layer_type type; }; -struct raw_pkt_parser; +struct layer_results +{ + struct layer_result layers[16]; + uint16_t layers_used; + uint16_t layers_size; +}; -struct raw_pkt_parser *raw_packet_parser_create(enum layer_type expect_type, uint16_t expect_results_num); -void raw_packet_parser_destory(struct raw_pkt_parser *handler); +struct raw_pkt_parser +{ + enum layer_type expect_type; + struct layer_results results; -// return 0 : success -// return -ENOMEM : error -int raw_packet_parser_push(struct raw_pkt_parser *handler, enum layer_type type, uint16_t offset); -// return PARSE_STATUS_CONTINUE -// return PARSE_STATUS_STOP -enum parse_status raw_packet_parser_status(struct raw_pkt_parser *handler, const void *data, enum layer_type this_type); + const void *ptr_pkt_start; + uint64_t pkt_trace_id; +}; + +void raw_packet_parser_init(struct raw_pkt_parser *handler, uint64_t pkt_trace_id, enum layer_type expect_type, uint16_t expect_results_num); // return most inner payload const void *raw_packet_parser_parse(struct raw_pkt_parser *handler, const void *data, size_t length); @@ -90,4 +96,4 @@ uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum l } #endif -#endif \ No newline at end of file +#endif diff --git a/common/include/utils.h b/common/include/utils.h index 904107f..b107110 100644 --- a/common/include/utils.h +++ b/common/include/utils.h @@ -9,7 +9,16 @@ extern "C" #define MIN(a, b) ((a) > (b) ? (a) : (b)) #define LOG_TAG_POLICY "POLICY" -#define LOG_TAG_UTILS "UTILS" +#define LOG_TAG_UTILS "UTILS" +#define LOG_TAG_RAWPKT "RAW_PACKET" +#define LOG_TAG_STABLE "SESSION_TABLE" +#define LOG_TAG_PKTIO "PACKET_IO" +#define LOG_TAG_METRICS "METRICS" +#define LOG_TAG_SCE "SCE" + +/****************************************************************************** + * fixed_num_array + ******************************************************************************/ struct fixed_num_array { @@ -21,9 +30,54 @@ struct fixed_num_array void fixed_num_array_init(struct fixed_num_array *array); void fixed_num_array_add_elem(struct fixed_num_array *array, int elem); void fixed_num_array_del_elem(struct fixed_num_array *array, int elem); +int fixed_num_array_is_full(struct fixed_num_array *array); int fixed_num_array_count_elem(struct fixed_num_array *array); +int fixed_num_array_exist_elem(struct fixed_num_array *array, int elem); int fixed_num_array_index_elem(struct fixed_num_array *array, int index); +/****************************************************************************** + * sids + ******************************************************************************/ + +#include "marsio.h" + +struct sids +{ + int num; + sid_t elems[MR_SID_LIST_MAXLEN]; +}; + +void sids_write_once(struct sids *dst, struct sids *src); +void sids_copy(struct sids *dst, struct sids *src); + +/****************************************************************************** + * throughput_metrics + ******************************************************************************/ + +struct throughput_metrics +{ + uint64_t n_pkts; + uint64_t n_bytes; +}; + +void throughput_metrics_inc(struct throughput_metrics *iterm, uint64_t n_pkts, uint64_t n_bytes); + +/****************************************************************************** + * protocol + ******************************************************************************/ + +void build_udp_header(const char *l3_hdr, int l3_hdr_len, struct udphdr *udp_hdr, u_int16_t udp_sport, u_int16_t udp_dport, int payload_len); +void build_ip_header(struct ip *ip_hdr, u_int8_t next_protocol, const char *src_addr, const char *dst_addr, uint16_t payload_len); +void build_ether_header(struct ethhdr *eth_hdr, uint16_t next_protocol, const char *src_mac, const char *dst_mac); + +/****************************************************************************** + * device + ******************************************************************************/ + +int get_ip_by_device_name(const char *dev_name, char *ip_buff); +int get_mac_by_device_name(const char *dev_name, char *mac_buff); +int str_to_mac(const char *str, char *mac_buff); + #ifdef __cpluscplus } #endif diff --git a/common/src/ctrl_packet.cpp b/common/src/ctrl_packet.cpp new file mode 100644 index 0000000..5dc2874 --- /dev/null +++ b/common/src/ctrl_packet.cpp @@ -0,0 +1,15 @@ +#include + +#include "ctrl_packet.h" + +void ctrl_packet_parser_init(struct ctrl_pkt_parser *handler) +{ + memset(handler, 0, sizeof(struct ctrl_pkt_parser)); +} + +// return 0 : success +// return -1 : error +int ctrl_packet_parser_parse(struct ctrl_pkt_parser *handler, const void *data, size_t length) +{ + return 0; +} \ No newline at end of file diff --git a/common/src/g_vxlan.cpp b/common/src/g_vxlan.cpp new file mode 100644 index 0000000..ec005c3 --- /dev/null +++ b/common/src/g_vxlan.cpp @@ -0,0 +1,67 @@ +#include +#include +#include + +#include "g_vxlan.h" + +void g_vxlan_set_packet_dir(struct g_vxlan *hdr, int dir_is_e2i) +{ + hdr->dir_is_e2i = (!!dir_is_e2i); +} + +void g_vxlan_set_chain_index(struct g_vxlan *hdr, int chain_index) +{ + hdr->chain_index = (0x1f & chain_index); +} + +void g_vxlan_set_traffic_type(struct g_vxlan *hdr, int traffic_is_decrypted) +{ + hdr->traffic_is_decrypted = (!!traffic_is_decrypted); +} + +int g_vxlan_get_packet_dir(struct g_vxlan *hdr) +{ + return (!!hdr->dir_is_e2i); +} + +int g_vxlan_get_chain_index(struct g_vxlan *hdr) +{ + return hdr->chain_index; +} + +int g_vxlan_get_traffic_type(struct g_vxlan *hdr) +{ + return (!!hdr->traffic_is_decrypted); +} + +// return 0 : success +// return -1 : error +int g_vxlan_decode(struct g_vxlan **g_vxlan_hdr, const char *raw_data, int raw_len) +{ + if (raw_len <= (int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct g_vxlan))) + { + return -1; + } + + struct ethhdr *eth_hdr = (struct ethhdr *)raw_data; + if (eth_hdr->h_proto != htons(ETH_P_IP)) + { + return -1; + } + + struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr)); + if (ip_hdr->ip_p != IPPROTO_UDP) + { + return -1; + } + + struct udphdr *udp_hdr = (struct udphdr *)((char *)ip_hdr + sizeof(struct ip)); + if (udp_hdr->uh_dport != htons(4789)) + { + return -1; + } + + *g_vxlan_hdr = (struct g_vxlan *)((char *)udp_hdr + sizeof(struct udphdr)); + + return 0; +} \ No newline at end of file diff --git a/common/src/raw_packet.cpp b/common/src/raw_packet.cpp index e71d21a..9cb8ef6 100644 --- a/common/src/raw_packet.cpp +++ b/common/src/raw_packet.cpp @@ -12,16 +12,21 @@ #include #include "log.h" +#include "utils.h" #include "uthash.h" #include "addr_tuple4.h" #include "raw_packet.h" -#define LOG_TAG "RAW_PACKET_PARSER" - /****************************************************************************** - * Protocol Struct + * Struct ******************************************************************************/ +enum parse_status +{ + PARSE_STATUS_CONTINUE, + PARSE_STATUS_STOP +}; + struct vlan_hdr { uint16_t vlan_cfi; @@ -58,38 +63,13 @@ struct gtp_hdr #define GTP_HDR_FLAG_SEQ_NUM (0x02) #define GTP_HDR_FLAG_NEXT_EXT_HDR (0x04) -/****************************************************************************** - * Parser Struct - ******************************************************************************/ - -static uint64_t packet_trace_id = 0; - -struct layer_result -{ - uint16_t offset; - enum layer_type type; -}; - -struct layer_result_array -{ - struct layer_result *layers; - uint16_t layers_used; - uint16_t layers_size; -}; - -struct raw_pkt_parser -{ - enum layer_type expect_type; - struct layer_result_array results; - - const void *ptr_pkt_start; - uint64_t pkt_trace_id; -}; - /****************************************************************************** * Static API ******************************************************************************/ +static int raw_packet_parser_push(struct raw_pkt_parser *handler, enum layer_type type, uint16_t offset); +static enum parse_status raw_packet_parser_status(struct raw_pkt_parser *handler, const void *data, enum layer_type this_type); + static const char *ldbc_method_to_string(enum ldbc_method ldbc_method); // parser utils @@ -115,82 +95,21 @@ static const void *parse_mpls(struct raw_pkt_parser *handler, const void *data, * Public API ******************************************************************************/ -struct raw_pkt_parser *raw_packet_parser_create(enum layer_type expect_type, uint16_t expect_results_num) +void raw_packet_parser_init(struct raw_pkt_parser *handler, uint64_t pkt_trace_id, enum layer_type expect_type, uint16_t expect_results_num) { - struct raw_pkt_parser *handler = (struct raw_pkt_parser *)calloc(1, sizeof(struct raw_pkt_parser)); - assert(handler); + memset(handler, 0, sizeof(struct raw_pkt_parser)); handler->expect_type = expect_type; - handler->results.layers = (struct layer_result *)calloc(expect_results_num, sizeof(struct layer_result)); - assert(handler->results.layers); handler->results.layers_used = 0; - handler->results.layers_size = expect_results_num; - - return handler; -} - -void raw_packet_parser_destory(struct raw_pkt_parser *handler) -{ - if (handler) - { - if (handler->results.layers) - { - free(handler->results.layers); - handler->results.layers = NULL; - } - - free(handler); - handler = NULL; - } -} - -// return 0 : success -// return -ENOMEM : error -int raw_packet_parser_push(struct raw_pkt_parser *handler, enum layer_type type, uint16_t offset) -{ - struct layer_result_array *result = &handler->results; - - if (result->layers_used >= result->layers_size) - { - return -ENOMEM; - } - - result->layers[result->layers_used].offset = offset; - result->layers[result->layers_used].type = type; - result->layers_used++; - - return 0; -} - -// return PARSE_STATUS_CONTINUE -// return PARSE_STATUS_STOP -enum parse_status raw_packet_parser_status(struct raw_pkt_parser *handler, const void *data, enum layer_type this_type) -{ - /* - * only when this_type & handler->expect_type is true, - * the information of the current layer will be recorded in results. - */ - if (!(this_type & handler->expect_type)) - { - return PARSE_STATUS_CONTINUE; - } - - uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->ptr_pkt_start); - if (raw_packet_parser_push(handler, this_type, offset) < 0) - { - return PARSE_STATUS_STOP; - } - else - { - return PARSE_STATUS_CONTINUE; - } + handler->results.layers_size = MIN(expect_results_num, (sizeof(handler->results.layers) / sizeof(handler->results.layers[0]))); + handler->ptr_pkt_start = NULL; + handler->pkt_trace_id = pkt_trace_id; } // return most inner payload const void *raw_packet_parser_parse(struct raw_pkt_parser *handler, const void *data, size_t length) { handler->ptr_pkt_start = data; - handler->pkt_trace_id = __atomic_fetch_add(&packet_trace_id, 1, __ATOMIC_RELAXED); // TESTED return parse_ether(handler, data, length, LAYER_TYPE_ETHER); @@ -204,7 +123,7 @@ int raw_packet_parser_get_most_inner_tuple4(struct raw_pkt_parser *handler, stru const char *l4_layer_data = NULL; const struct layer_result *l3_layer_result = NULL; const struct layer_result *l4_layer_result = NULL; - struct layer_result_array *results = &handler->results; + struct layer_results *results = &handler->results; // search L4 layer and L3 layer in reverse order for (int8_t i = results->layers_used - 1; i >= 0; i--) @@ -212,7 +131,7 @@ int raw_packet_parser_get_most_inner_tuple4(struct raw_pkt_parser *handler, stru const struct layer_result *layer = &results->layers[i]; enum layer_type type = layer->type; - LOG_DEBUG("%s: find most inner tuple4, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); + LOG_DEBUG("%s: find most inner tuple4, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); // first get L4 layer if (type & LAYER_TYPE_L4) @@ -259,7 +178,7 @@ int raw_packet_parser_get_most_outer_tuple4(struct raw_pkt_parser *handler, stru const char *l4_layer_data = NULL; const struct layer_result *l3_layer_result = NULL; const struct layer_result *l4_layer_result = NULL; - struct layer_result_array *results = &handler->results; + struct layer_results *results = &handler->results; // search L3 layer and L4 layer in order for (int8_t i = 0; i <= results->layers_used - 1; i++) @@ -267,7 +186,7 @@ int raw_packet_parser_get_most_outer_tuple4(struct raw_pkt_parser *handler, stru const struct layer_result *layer = &results->layers[i]; enum layer_type type = layer->type; - LOG_DEBUG("%s: find most outer tuple4, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); + LOG_DEBUG("%s: find most outer tuple4, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); // first get L3 layer if (type & LAYER_TYPE_L3) @@ -311,7 +230,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) { const char *l3_layer_data = NULL; - struct layer_result_array *results = &handler->results; + struct layer_results *results = &handler->results; // search L3 layer in reverse order for (int8_t i = results->layers_used - 1; i >= 0; i--) @@ -319,7 +238,7 @@ int raw_packet_parser_get_most_inner_address(struct raw_pkt_parser *handler, str const struct layer_result *layer = &results->layers[i]; enum layer_type type = layer->type; - LOG_DEBUG("%s: find most inner address, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); + LOG_DEBUG("%s: find most inner address, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); if (type & LAYER_TYPE_L3) { l3_layer_data = (const char *)handler->ptr_pkt_start + layer->offset; @@ -336,7 +255,7 @@ int raw_packet_parser_get_most_inner_address(struct raw_pkt_parser *handler, str int raw_packet_parser_get_most_outer_address(struct raw_pkt_parser *handler, struct addr_tuple4 *addr) { const char *l3_layer_data = NULL; - struct layer_result_array *results = &handler->results; + struct layer_results *results = &handler->results; // search L3 layer in order for (int8_t i = 0; i <= results->layers_used - 1; i++) @@ -344,7 +263,7 @@ int raw_packet_parser_get_most_outer_address(struct raw_pkt_parser *handler, str const struct layer_result *layer = &results->layers[i]; enum layer_type type = layer->type; - LOG_DEBUG("%s: find most outer address, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); + LOG_DEBUG("%s: find most outer address, pkt_trace_id: %lu, layer[%d/%d]: %s", LOG_TAG_RAWPKT, handler->pkt_trace_id, i, results->layers_size, layer_type2str(type)); if (type & LAYER_TYPE_L3) { l3_layer_data = (const char *)handler->ptr_pkt_start + layer->offset; @@ -477,7 +396,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_ERROR("%s: pkt_trace_id: %lu, outer_addr: %s, inner_addr: %s, is_internal: %d, hash_method: %s, hash_value: %lu", - LOG_TAG, 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_internal, ldbc_method_to_string(method), hash_value); free(inner_addr_str); free(outer_addr_str); @@ -488,6 +407,48 @@ uint64_t raw_packet_parser_get_hash_value(struct raw_pkt_parser *handler, enum l * Private API ******************************************************************************/ +// return 0 : success +// return -ENOMEM : error +static int raw_packet_parser_push(struct raw_pkt_parser *handler, enum layer_type type, uint16_t offset) +{ + struct layer_results *result = &handler->results; + + if (result->layers_used >= result->layers_size) + { + return -ENOMEM; + } + + result->layers[result->layers_used].offset = offset; + result->layers[result->layers_used].type = type; + result->layers_used++; + + return 0; +} + +// return PARSE_STATUS_CONTINUE +// return PARSE_STATUS_STOP +static enum parse_status raw_packet_parser_status(struct raw_pkt_parser *handler, const void *data, enum layer_type this_type) +{ + /* + * only when this_type & handler->expect_type is true, + * the information of the current layer will be recorded in results. + */ + if (!(this_type & handler->expect_type)) + { + return PARSE_STATUS_CONTINUE; + } + + uint16_t offset = (uintptr_t)data - (uintptr_t)(handler->ptr_pkt_start); + if (raw_packet_parser_push(handler, this_type, offset) < 0) + { + return PARSE_STATUS_STOP; + } + else + { + return PARSE_STATUS_CONTINUE; + } +} + static const char *ldbc_method_to_string(enum ldbc_method ldbc_method) { switch (ldbc_method) @@ -629,7 +590,7 @@ static const void *parse_ether(struct raw_pkt_parser *handler, const void *data, { if (length < sizeof(struct ethhdr)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -644,7 +605,7 @@ static const void *parse_ether(struct raw_pkt_parser *handler, const void *data, const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (next_proto) { case ETH_P_8021Q: @@ -666,7 +627,7 @@ static const void *parse_ether(struct raw_pkt_parser *handler, const void *data, // TESTED return parse_mpls(handler, data_next_layer, data_next_length, LAYER_TYPE_MPLS); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -675,7 +636,7 @@ static const void *parse_ipv4(struct raw_pkt_parser *handler, const void *data, { if (length < sizeof(struct ip)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -690,7 +651,7 @@ static const void *parse_ipv4(struct raw_pkt_parser *handler, const void *data, const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (next_proto) { case IPPROTO_TCP: @@ -706,7 +667,7 @@ static const void *parse_ipv4(struct raw_pkt_parser *handler, const void *data, // TESTED return parse_ipv6(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV6); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -715,7 +676,7 @@ static const void *parse_ipv6(struct raw_pkt_parser *handler, const void *data, { if (length < sizeof(struct ip6_hdr)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -730,7 +691,7 @@ static const void *parse_ipv6(struct raw_pkt_parser *handler, const void *data, const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (next_proto) { case IPPROTO_TCP: @@ -746,7 +707,7 @@ static const void *parse_ipv6(struct raw_pkt_parser *handler, const void *data, // TESTED return parse_ipv6(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV6); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -755,7 +716,7 @@ static const void *parse_tcp(struct raw_pkt_parser *handler, const void *data, s { if (length < sizeof(struct tcphdr)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -769,7 +730,7 @@ static const void *parse_tcp(struct raw_pkt_parser *handler, const void *data, s const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); return data_next_layer; } @@ -778,7 +739,7 @@ static const void *parse_udp(struct raw_pkt_parser *handler, const void *data, s { if (length < sizeof(struct udphdr)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -792,7 +753,7 @@ static const void *parse_udp(struct raw_pkt_parser *handler, const void *data, s const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (ntohs(hdr->uh_dport)) { // VXLAN_DPORT @@ -812,7 +773,7 @@ static const void *parse_ppp(struct raw_pkt_parser *handler, const void *data, s { if (length < PPP_HDRLEN) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -826,7 +787,7 @@ static const void *parse_ppp(struct raw_pkt_parser *handler, const void *data, s const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (next_proto) { case PPP_IP: @@ -836,7 +797,7 @@ static const void *parse_ppp(struct raw_pkt_parser *handler, const void *data, s // TODO return parse_ipv6(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV6); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -845,7 +806,7 @@ static const void *parse_pppoe_ses(struct raw_pkt_parser *handler, const void *d { if (length < 8) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -859,7 +820,7 @@ static const void *parse_pppoe_ses(struct raw_pkt_parser *handler, const void *d const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (next_proto) { // PPPOE_TYPE_IPV4 @@ -871,7 +832,7 @@ static const void *parse_pppoe_ses(struct raw_pkt_parser *handler, const void *d // TODO return parse_ipv6(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV6); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -880,7 +841,7 @@ static const void *parse_hdlc(struct raw_pkt_parser *handler, const void *data, { if (length < 4) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -894,7 +855,7 @@ static const void *parse_hdlc(struct raw_pkt_parser *handler, const void *data, const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); // HDLC的协议字段与以太网的类似,对于IPv4,为0x0800 switch (next_proto) { @@ -907,7 +868,7 @@ static const void *parse_hdlc(struct raw_pkt_parser *handler, const void *data, // TODO return parse_ipv6(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV6); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -916,7 +877,7 @@ static const void *parse_vxlan(struct raw_pkt_parser *handler, const void *data, { if (length < sizeof(struct vxlan_hdr)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return NULL; } @@ -930,7 +891,7 @@ static const void *parse_vxlan(struct raw_pkt_parser *handler, const void *data, const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); // TESTED return parse_ether(handler, data_next_layer, data_next_length, LAYER_TYPE_ETHER); @@ -942,7 +903,7 @@ static const void *parse_vlan8021q(struct raw_pkt_parser *handler, const void *d { if (length < sizeof(struct vlan_hdr)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return NULL; } @@ -957,7 +918,7 @@ static const void *parse_vlan8021q(struct raw_pkt_parser *handler, const void *d const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (next_proto) { case ETH_P_8021Q: @@ -976,7 +937,7 @@ static const void *parse_vlan8021q(struct raw_pkt_parser *handler, const void *d // TODO return parse_mpls(handler, data_next_layer, data_next_length, LAYER_TYPE_MPLS); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -985,7 +946,7 @@ static const void *parse_gtpv1_u(struct raw_pkt_parser *handler, const void *dat { if (length < sizeof(struct gtp_hdr)) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return NULL; } @@ -1004,7 +965,7 @@ static const void *parse_gtpv1_u(struct raw_pkt_parser *handler, const void *dat const void *data_next_layer = (const char *)data + hdr_len; size_t data_next_length = length - hdr_len; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); switch (next_proto) { case 4: @@ -1014,7 +975,7 @@ static const void *parse_gtpv1_u(struct raw_pkt_parser *handler, const void *dat // TESTED return parse_ipv6(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV6); default: - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), next_proto); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, stop parse next protocol %d", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), next_proto); return data_next_layer; } } @@ -1023,7 +984,7 @@ static const void *parse_mpls(struct raw_pkt_parser *handler, const void *data, { if (length < 4) { - LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type)); + LOG_ERROR("%s: pkt_trace_id: %lu, this_layer: %s, err: data not enough", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type)); return data; } @@ -1077,32 +1038,32 @@ static const void *parse_mpls(struct raw_pkt_parser *handler, const void *data, data_next_layer = (const char *)data_next_layer + 4; data_next_length = data_next_length - 4; - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); // TESTED return parse_ether(handler, data_next_layer, data_next_length, LAYER_TYPE_ETHER); } else if (ip_version == 4) { - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); // TESTED return parse_ipv4(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV4); } else if (ip_version == 6) { - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); // TODO return parse_ipv6(handler, data_next_layer, data_next_length, LAYER_TYPE_IPV6); } else { - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); // TODO return parse_ether(handler, data_next_layer, data_next_length, LAYER_TYPE_ETHER); } } else { - LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); + LOG_DEBUG("%s: pkt_trace_id: %lu, this_layer: %s, payload_len: [%lu/%lu]", LOG_TAG_RAWPKT, handler->pkt_trace_id, layer_type2str(this_type), data_next_length, length); // TESTED return parse_mpls(handler, data_next_layer, data_next_length, LAYER_TYPE_MPLS); } diff --git a/common/src/session_table.cpp b/common/src/session_table.cpp index fb141e9..a58b8f7 100644 --- a/common/src/session_table.cpp +++ b/common/src/session_table.cpp @@ -1,6 +1,7 @@ #include #include "session_table.h" +#include "utils.h" #include "log.h" struct session_table @@ -66,7 +67,7 @@ int session_table_insert(struct session_table *table, uint64_t session_id, const HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp); if (temp) { - LOG_DEBUG("session table insert: key %lu exists", session_id); + LOG_DEBUG("%s: insert: key %lu exists", LOG_TAG_STABLE, session_id); return -1; } @@ -81,7 +82,7 @@ int session_table_insert(struct session_table *table, uint64_t session_id, const 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("session table insert: key %lu success", session_id); + LOG_DEBUG("%s: insert: key %lu success", LOG_TAG_STABLE, session_id); table->session_node_count++; return 0; @@ -93,7 +94,7 @@ 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("session table delete: key %lu not exists", session_id); + LOG_DEBUG("%s: delete: key %lu not exists", LOG_TAG_STABLE, session_id); return -1; } @@ -109,7 +110,7 @@ int session_table_delete_by_id(struct session_table *table, uint64_t session_id) free(temp); temp = NULL; - LOG_DEBUG("session table delete: key %lu success", session_id); + LOG_DEBUG("%s: delete: key %lu success", LOG_TAG_STABLE, session_id); table->session_node_count--; return 0; @@ -127,7 +128,7 @@ 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("session table delete: key %s not exists", addr_str); + LOG_DEBUG("%s: delete: key %s not exists", LOG_TAG_STABLE, addr_str); free(addr_str); return -1; } @@ -145,7 +146,7 @@ int session_table_delete_by_addr(struct session_table *table, const struct addr_ free(temp); temp = NULL; - LOG_DEBUG("session table delete: key %s success", addr_str); + LOG_DEBUG("%s: delete: key %s success", LOG_TAG_STABLE, addr_str); free(addr_str); addr_str = NULL; table->session_node_count--; @@ -159,11 +160,11 @@ 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("session table search: key %lu not exists", session_id); + LOG_DEBUG("%s: search: key %lu not exists", LOG_TAG_STABLE, session_id); return NULL; } - LOG_DEBUG("session table search: key %lu success", session_id); + LOG_DEBUG("%s: search: key %lu success", LOG_TAG_STABLE, session_id); return temp; } @@ -180,14 +181,14 @@ 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("session table search: key %s not exists", addr_str); + LOG_DEBUG("%s: search: key %s not exists", LOG_TAG_STABLE, addr_str); free(addr_str); addr_str = NULL; return NULL; } } - LOG_DEBUG("session table search: key %s success", addr_str); + LOG_DEBUG("%s: search: key %s success", LOG_TAG_STABLE, addr_str); free(addr_str); addr_str = NULL; diff --git a/common/src/utils.cpp b/common/src/utils.cpp index 10f2268..699e424 100644 --- a/common/src/utils.cpp +++ b/common/src/utils.cpp @@ -1,9 +1,21 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "utils.h" #include "log.h" +/****************************************************************************** + * fixed_num_array + ******************************************************************************/ + void fixed_num_array_init(struct fixed_num_array *array) { memset(array, 0, sizeof(fixed_num_array)); @@ -40,6 +52,18 @@ void fixed_num_array_del_elem(struct fixed_num_array *array, int elem) } } +int fixed_num_array_is_full(struct fixed_num_array *array) +{ + if (array->num == array->size) + { + return 1; + } + else + { + return 0; + } +} + int fixed_num_array_count_elem(struct fixed_num_array *array) { if (array) @@ -52,6 +76,19 @@ int fixed_num_array_count_elem(struct fixed_num_array *array) } } +int fixed_num_array_exist_elem(struct fixed_num_array *array, int elem) +{ + for (int i = 0; i < array->num; i++) + { + if (array->elems[i] == elem) + { + return 1; + } + } + + return 0; +} + int fixed_num_array_index_elem(struct fixed_num_array *array, int index) { if (index >= array->num) @@ -60,4 +97,178 @@ int fixed_num_array_index_elem(struct fixed_num_array *array, int index) } return array->elems[index]; -} \ No newline at end of file +} + +/****************************************************************************** + * sids + ******************************************************************************/ + +void sids_write_once(struct sids *dst, struct sids *src) +{ + if (dst && src) + { + if (dst->num == 0 && src->num > 0) + { + sids_copy(dst, src); + } + } +} + +void sids_copy(struct sids *dst, struct sids *src) +{ + if (dst && src) + { + dst->num = src->num; + memcpy(dst->elems, src->elems, sizeof(dst->elems[0]) * dst->num); + } +} + +/****************************************************************************** + * throughput_metrics + ******************************************************************************/ + +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); +} + +/****************************************************************************** + * protocol + ******************************************************************************/ + +#define CHECKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff)) + +static int checksum(u_int16_t *addr, int len) +{ + int sum = 0; + int nleft = len; + u_int16_t ans = 0; + u_int16_t *w = addr; + + while (nleft > 1) + { + sum += *w++; + nleft -= 2; + } + + if (nleft == 1) + { + *(char *)(&ans) = *(char *)w; + sum += ans; + } + + return sum; +} + +void build_udp_header(const char *l3_hdr, int l3_hdr_len, struct udphdr *udp_hdr, u_int16_t udp_sport, u_int16_t udp_dport, int payload_len) +{ + memset(udp_hdr, 0, sizeof(struct udphdr)); + + int udp_hlen = sizeof(struct udphdr) + payload_len; + + udp_hdr->uh_sport = htons(udp_sport); + udp_hdr->uh_dport = htons(udp_dport); + + udp_hdr->uh_ulen = htons(udp_hlen); + udp_hdr->uh_sum = 0; + + int sum = checksum((u_int16_t *)l3_hdr, l3_hdr_len); + sum += ntohs(IPPROTO_UDP + udp_hlen); + sum += checksum((u_int16_t *)udp_hdr, udp_hlen); + udp_hdr->uh_sum = CHECKSUM_CARRY(sum); +} + +void build_ip_header(struct ip *ip_hdr, u_int8_t next_protocol, const char *src_addr, const char *dst_addr, uint16_t payload_len) +{ + memset(ip_hdr, 0, sizeof(struct ip)); + + ip_hdr->ip_hl = 5; /* 20 byte header */ + ip_hdr->ip_v = 4; /* version 4 */ + ip_hdr->ip_tos = 0; /* IP tos */ + ip_hdr->ip_id = htons(random()); /* IP ID */ + ip_hdr->ip_ttl = 80; /* time to live */ + ip_hdr->ip_p = next_protocol; /* transport protocol */ + ip_hdr->ip_src.s_addr = inet_addr(src_addr); + ip_hdr->ip_dst.s_addr = inet_addr(dst_addr); + ip_hdr->ip_len = htons(sizeof(struct ip) + payload_len); /* total length */ + ip_hdr->ip_off = htons(0); /* fragmentation flags */ + ip_hdr->ip_sum = 0; /* do this later */ + + int sum = checksum((u_int16_t *)ip_hdr, 20); + ip_hdr->ip_sum = CHECKSUM_CARRY(sum); +} + +// l3_protocol: ETH_P_IPV6/ETH_P_IP +void build_ether_header(struct ethhdr *eth_hdr, uint16_t next_protocol, const char *src_mac, const char *dst_mac) +{ + memset(eth_hdr, 0, sizeof(struct ethhdr)); + + str_to_mac(src_mac, (char *)eth_hdr->h_source); + str_to_mac(dst_mac, (char *)eth_hdr->h_dest); + eth_hdr->h_proto = htons(next_protocol); +} + +/****************************************************************************** + * device + ******************************************************************************/ + +int get_ip_by_device_name(const char *dev_name, char *ip_buff) +{ + int fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) + { + return -1; + } + + struct ifreq ifr; + memset(&ifr, 0, sizeof(struct ifreq)); + ifr.ifr_addr.sa_family = AF_INET; + strcpy(ifr.ifr_name, dev_name); + if (ioctl(fd, SIOCGIFADDR, &ifr) != 0) + { + close(fd); + return -1; + } + + strcpy(ip_buff, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); + close(fd); + + return 0; +} + +int get_mac_by_device_name(const char *dev_name, char *mac_buff) +{ + int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd == -1) + { + return -1; + } + + struct ifreq ifr; + memset(&ifr, 0, sizeof(struct ifreq)); + strcpy(ifr.ifr_name, dev_name); + if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0) + { + close(fd); + return -1; + } + + unsigned char *mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; + sprintf(mac_buff, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + close(fd); + + return 0; +} + +int str_to_mac(const char *str, char *mac_buff) +{ + if (sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &(mac_buff[0]), &(mac_buff[1]), &(mac_buff[2]), &(mac_buff[3]), &(mac_buff[4]), &(mac_buff[5])) == 6) + { + return 0; + } + else + { + return -1; + } +} diff --git a/common/test/gtest_raw_packet.cpp b/common/test/gtest_raw_packet.cpp index 6badb1f..47b4af6 100644 --- a/common/test/gtest_raw_packet.cpp +++ b/common/test/gtest_raw_packet.cpp @@ -77,10 +77,10 @@ unsigned char data1[] = { TEST(RAW_PACKET, ETH_VLAN_VLAN_IP4_IP4_UDP) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data1, sizeof(data1)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data1, sizeof(data1)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data1 == 70); @@ -91,8 +91,8 @@ TEST(RAW_PACKET, ETH_VLAN_VLAN_IP4_IP4_UDP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "10.10.100.25 62367 10.10.101.2 17000"); @@ -102,16 +102,14 @@ TEST(RAW_PACKET, ETH_VLAN_VLAN_IP4_IP4_UDP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "10.10.100.25 0 10.10.101.2 0"); EXPECT_STREQ(outer_addr_str, "69.67.35.146 0 41.202.46.110 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -210,10 +208,10 @@ unsigned char data2[] = { TEST(RAW_PACKET, ETH_IP6_IP4_TCP_SSH) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data2, sizeof(data2)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data2, sizeof(data2)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data2 == 94); @@ -224,8 +222,8 @@ TEST(RAW_PACKET, ETH_IP6_IP4_TCP_SSH) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "1.1.1.1 57639 2.2.2.2 22"); @@ -235,16 +233,14 @@ TEST(RAW_PACKET, ETH_IP6_IP4_TCP_SSH) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "1.1.1.1 0 2.2.2.2 0"); EXPECT_STREQ(outer_addr_str, "2001::192:168:40:134 0 2001::192:168:40:133 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -338,10 +334,10 @@ unsigned char data3[] = { #if 0 TEST(RAW_PACKET, ETH_VLAN_IP6_IP4_GRE_PPP_IP4_UDP_DNS) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0 , LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data3, sizeof(data3)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data3, sizeof(data3)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data3 == 126); @@ -352,8 +348,8 @@ TEST(RAW_PACKET, ETH_VLAN_IP6_IP4_GRE_PPP_IP4_UDP_DNS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "8.8.8.8 53 172.16.44.3 9879"); @@ -363,16 +359,14 @@ TEST(RAW_PACKET, ETH_VLAN_IP6_IP4_GRE_PPP_IP4_UDP_DNS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "8.8.8.8 0 172.16.44.3 0"); EXPECT_STREQ(outer_addr_str, "2607:fcd0:100:2300::b108:2a6b 0 2402:f000:1:8e01::5555 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } #endif @@ -441,10 +435,10 @@ unsigned char data4[] = { TEST(RAW_PACKET, ETH_IP4_IP6_TCP) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data4, sizeof(data4)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data4, sizeof(data4)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data4 == 106); @@ -455,8 +449,8 @@ TEST(RAW_PACKET, ETH_IP4_IP6_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "2001:da8:200:900e:200:5efe:d24d:58a3 52556 2600:140e:6::1702:1058 80"); @@ -466,16 +460,14 @@ TEST(RAW_PACKET, ETH_IP4_IP6_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "2001:da8:200:900e:200:5efe:d24d:58a3 0 2600:140e:6::1702:1058 0"); EXPECT_STREQ(outer_addr_str, "210.77.88.163 0 59.66.4.50 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -529,10 +521,10 @@ unsigned char data5[] = { TEST(RAW_PACKET, ETH_IP6_IP6_UDP) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data5, sizeof(data5)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data5, sizeof(data5)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data5 == 102); @@ -543,8 +535,8 @@ TEST(RAW_PACKET, ETH_IP6_IP6_UDP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "dead::beef 30000 cafe::babe 13000"); @@ -554,16 +546,14 @@ TEST(RAW_PACKET, ETH_IP6_IP6_UDP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "dead::beef 0 cafe::babe 0"); EXPECT_STREQ(outer_addr_str, "2001:4f8:4:7:2e0:81ff:fe52:ffff 0 2001:4f8:4:7:2e0:81ff:fe52:9a6b 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -624,10 +614,10 @@ unsigned char data6[] = { TEST(RAW_PACKET, ETH_MPLS_IP4_TCP) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data6, sizeof(data6)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data6, sizeof(data6)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data6 == 70); @@ -638,8 +628,8 @@ TEST(RAW_PACKET, ETH_MPLS_IP4_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "119.40.37.65 61853 123.125.29.250 80"); @@ -649,16 +639,14 @@ TEST(RAW_PACKET, ETH_MPLS_IP4_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "119.40.37.65 0 123.125.29.250 0"); EXPECT_STREQ(outer_addr_str, "119.40.37.65 0 123.125.29.250 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -724,10 +712,10 @@ unsigned char data7[] = { TEST(RAW_PACKET, ETH_MPLS_MPLS_IP4_TCP) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data7, sizeof(data7)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data7, sizeof(data7)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data7 == 66); @@ -738,8 +726,8 @@ TEST(RAW_PACKET, ETH_MPLS_MPLS_IP4_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "10.31.0.1 11001 10.34.0.1 23"); @@ -749,16 +737,14 @@ TEST(RAW_PACKET, ETH_MPLS_MPLS_IP4_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "10.31.0.1 0 10.34.0.1 0"); EXPECT_STREQ(outer_addr_str, "10.31.0.1 0 10.34.0.1 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -829,10 +815,10 @@ unsigned char data8[] = { TEST(RAW_PACKET, ETH_VLAN_PPPOE_IP4_TCP) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data8, sizeof(data8)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data8, sizeof(data8)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data8 == 78); @@ -843,8 +829,8 @@ TEST(RAW_PACKET, ETH_VLAN_PPPOE_IP4_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "100.65.55.0 34532 91.185.14.33 443"); @@ -854,16 +840,14 @@ TEST(RAW_PACKET, ETH_VLAN_PPPOE_IP4_TCP) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "100.65.55.0 0 91.185.14.33 0"); EXPECT_STREQ(outer_addr_str, "100.65.55.0 0 91.185.14.33 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -993,10 +977,10 @@ unsigned char data9[] = { TEST(RAW_PACKET, ETH_IP6_UDP_GTP_IP6_TCP_TLS) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data9, sizeof(data9)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data9, sizeof(data9)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data9 == 130); @@ -1007,8 +991,8 @@ TEST(RAW_PACKET, ETH_IP6_UDP_GTP_IP6_TCP_TLS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "2409:8c34:4400:700:0:4:0:3 443 2409:8934:5082:2100:ecad:e0e4:530a:c269 46582"); @@ -1018,16 +1002,14 @@ TEST(RAW_PACKET, ETH_IP6_UDP_GTP_IP6_TCP_TLS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "2409:8c34:4400:700:0:4:0:3 0 2409:8934:5082:2100:ecad:e0e4:530a:c269 0"); EXPECT_STREQ(outer_addr_str, "2409:8034:4040:5300::105 0 2409:8034:4025::60:61 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -1164,10 +1146,10 @@ unsigned char data10[] = { TEST(RAW_PACKET, ETH_IP6_UDP_GTP_IP4_TCP_TLS) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data10, sizeof(data10)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data10, sizeof(data10)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data10 == 122); @@ -1178,8 +1160,8 @@ TEST(RAW_PACKET, ETH_IP6_UDP_GTP_IP4_TCP_TLS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "10.49.115.138 50081 121.196.250.66 443"); @@ -1189,16 +1171,14 @@ TEST(RAW_PACKET, ETH_IP6_UDP_GTP_IP4_TCP_TLS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "10.49.115.138 0 121.196.250.66 0"); EXPECT_STREQ(outer_addr_str, "2409:8034:4025::50:a31 0 2409:8034:4040:5301::204 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -1277,10 +1257,10 @@ unsigned char data11[] = { TEST(RAW_PACKET, ETH_IP4_UDP_VXLAN_ETH_IP4_UDP_DNS) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data11, sizeof(data11)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data11, sizeof(data11)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data11 == 92); @@ -1291,8 +1271,8 @@ TEST(RAW_PACKET, ETH_IP4_UDP_VXLAN_ETH_IP4_UDP_DNS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "192.168.11.193 65290 114.114.114.114 53"); @@ -1302,16 +1282,14 @@ TEST(RAW_PACKET, ETH_IP4_UDP_VXLAN_ETH_IP4_UDP_DNS) memset(&inner_addr, 0, sizeof(inner_addr)); memset(&outer_addr, 0, sizeof(outer_addr)); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == 0); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == 0); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == 0); inner_addr_str = addr_tuple4_to_str(&inner_addr); outer_addr_str = addr_tuple4_to_str(&outer_addr); EXPECT_STREQ(inner_addr_str, "192.168.11.193 0 114.114.114.114 0"); EXPECT_STREQ(outer_addr_str, "10.1.1.1 0 192.168.1.10 0"); free(inner_addr_str); free(outer_addr_str); - - raw_packet_parser_destory(handler); } /****************************************************************************** @@ -1352,44 +1330,40 @@ unsigned char data12[] = { TEST(RAW_PACKET, ETH_MPLS_MPLS_PWETHCW_ETH_ARP) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data12, sizeof(data12)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data12, sizeof(data12)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data12 == 40); struct addr_tuple4 inner_addr; struct addr_tuple4 outer_addr; - EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(handler, &inner_addr) == -1); - EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(handler, &outer_addr) == -1); + EXPECT_TRUE(raw_packet_parser_get_most_inner_tuple4(&handler, &inner_addr) == -1); + EXPECT_TRUE(raw_packet_parser_get_most_outer_tuple4(&handler, &outer_addr) == -1); - EXPECT_TRUE(raw_packet_parser_get_most_inner_address(handler, &inner_addr) == -1); - EXPECT_TRUE(raw_packet_parser_get_most_outer_address(handler, &outer_addr) == -1); - - raw_packet_parser_destory(handler); + EXPECT_TRUE(raw_packet_parser_get_most_inner_address(&handler, &inner_addr) == -1); + EXPECT_TRUE(raw_packet_parser_get_most_outer_address(&handler, &outer_addr) == -1); } TEST(RAW_PACKET, GET_HASH_VALUE) { - struct raw_pkt_parser *handler = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(handler != nullptr); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); - const void *payload = raw_packet_parser_parse(handler, (const void *)data4, sizeof(data4)); + const void *payload = raw_packet_parser_parse(&handler, (const void *)data4, sizeof(data4)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data4 == 106); // inner_addr_str: "2001:da8:200:900e:200:5efe:d24d:58a3 0 2600:140e:6::1702:1058 0" // outer_addr_str: "210.77.88.163 0 59.66.4.50 0" - EXPECT_TRUE(raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_INT_IP, 1) == raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_EXT_IP, 0)); - EXPECT_TRUE(raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_EXT_IP, 1) == raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_INT_IP, 0)); + EXPECT_TRUE(raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_INT_IP, 1) == raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_EXT_IP, 0)); + EXPECT_TRUE(raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_EXT_IP, 1) == raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_INT_IP, 0)); - EXPECT_TRUE(raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, 1) == raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, 0)); - EXPECT_TRUE(raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_INNERMOST_INT_IP, 1) == raw_packet_parser_get_hash_value(handler, LDBC_METHOD_HASH_INNERMOST_EXT_IP, 0)); - - raw_packet_parser_destory(handler); + EXPECT_TRUE(raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, 1) == raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, 0)); + EXPECT_TRUE(raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_INNERMOST_INT_IP, 1) == raw_packet_parser_get_hash_value(&handler, LDBC_METHOD_HASH_INNERMOST_EXT_IP, 0)); } int main(int argc, char **argv) diff --git a/common/test/gtest_utils.cpp b/common/test/gtest_utils.cpp index 6d75a71..a4d8c7c 100644 --- a/common/test/gtest_utils.cpp +++ b/common/test/gtest_utils.cpp @@ -36,6 +36,70 @@ TEST(UTILS, FIXED_NUM_ARRAY) EXPECT_TRUE(fixed_num_array_count_elem(&array) == 0); } +TEST(UTILS, SIDS) +{ + struct sids src; + struct sids dst; + + // set src + for (int i = 0; i < MR_SID_LIST_MAXLEN; i++) + { + src.elems[i] = i; + } + src.num = MR_SID_LIST_MAXLEN; + + // copy src to dst + memset(&dst, 0, sizeof(struct sids)); + sids_write_once(&dst, &src); + + // check dst + EXPECT_TRUE(dst.num == src.num); + for (int i = 0; i < MR_SID_LIST_MAXLEN; i++) + { + EXPECT_TRUE(dst.elems[i] == i); + } + + // update src + for (int i = 0; i < MR_SID_LIST_MAXLEN; i++) + { + src.elems[i] = i * 2; + } + + // copy src to dst + sids_write_once(&dst, &src); + + // check dst + EXPECT_TRUE(dst.num == src.num); + for (int i = 0; i < MR_SID_LIST_MAXLEN; i++) + { + EXPECT_TRUE(dst.elems[i] == i); + } +} + +TEST(UTILS, THROUGHPUT_METRICS) +{ + struct throughput_metrics iterm = {.n_pkts = 0, .n_bytes = 0}; + throughput_metrics_inc(&iterm, 1, 2); + EXPECT_TRUE(iterm.n_pkts == 1); + EXPECT_TRUE(iterm.n_bytes == 2); +} + +TEST(UTILS, DEVICE) +{ + const char *dev_name = "lo"; + char ip_buff[16] = {0}; + char mac_buff[32] = {0}; + + EXPECT_TRUE(get_ip_by_device_name(dev_name, ip_buff) == 0); + EXPECT_TRUE(get_mac_by_device_name(dev_name, mac_buff) == 0); + + printf("Dev : %s, IP : %s\n", dev_name, ip_buff); + printf("Dev : %s, MAC : %s\n", dev_name, mac_buff); + + EXPECT_STREQ(ip_buff, "127.0.0.1"); + EXPECT_STREQ(mac_buff, "00:00:00:00:00:00"); +} + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/conf/sce.conf b/conf/sce.conf index 3044ce9..cda9261 100644 --- a/conf/sce.conf +++ b/conf/sce.conf @@ -1,5 +1,6 @@ [system] nr_worker_threads=8 +firewall_sids=1001 [maat] # 0:json 1:redis 2:iris @@ -18,4 +19,17 @@ json_cfg_file=resource/sce.json foreign_cont_dir=resource/foreign_files redis_db_idx=0 redis_server=127.0.0.1 -redis_port_range=6379 \ No newline at end of file +redis_port_range=6379 + +[packet_io] +# bypass_all_traffic:1 NF2NF and SF2SF +# bypass_all_traffic:1 NF2SF and SF2NF +bypass_all_traffic=0 +rx_burst_max=128 +app_symbol=sce +dev_endpoint=eth_sf_endpoint +dev_nf_interface=eth_nf_interface +default_src_ip=192.168.100.1 +default_dst_ip=192.168.100.2 +default_src_mac=aa:aa:aa:aa:aa:aa +default_dst_mac=bb:bb:bb:bb:bb:bb \ No newline at end of file diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index ba67e1d..6989130 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -1,9 +1,10 @@ -add_library(platform src/policy.cpp src/health_check.cpp) +add_library(platform src/policy.cpp src/health_check.cpp src/sce.cpp src/packet_io.cpp) target_link_libraries(platform PUBLIC common) target_link_libraries(platform PUBLIC pthread) target_link_libraries(platform PUBLIC MESA_handle_logger) target_link_libraries(platform PUBLIC MESA_prof_load) target_link_libraries(platform PUBLIC maatframe) +target_link_libraries(platform PUBLIC mrzcpd) target_link_libraries(platform PUBLIC cjson) target_include_directories(platform PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/) diff --git a/platform/include/packet_io.h b/platform/include/packet_io.h new file mode 100644 index 0000000..4c5b34b --- /dev/null +++ b/platform/include/packet_io.h @@ -0,0 +1,19 @@ +#ifndef _PACKET_IO_H +#define _PACKET_IO_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +struct packet_io *packet_io_create(const char *profile, int thread_num); +void packet_io_destory(struct packet_io *handle); + +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); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/platform/include/policy.h b/platform/include/policy.h index 874dae5..570a97b 100644 --- a/platform/include/policy.h +++ b/platform/include/policy.h @@ -6,6 +6,7 @@ extern "C" { #endif +#include "utils.h" #include "raw_packet.h" enum traffic_type @@ -82,23 +83,27 @@ struct connectivity struct selected_sf { + int policy_id; + enum traffic_type traffic_type; + int sff_profile_id; enum forward_type sff_forward_type; + int sf_need_skip; int sf_profile_id; enum session_action sf_action; enum session_action_reason sf_action_reason; struct connectivity sf_connectivity; + + struct throughput_metrics rx; + struct throughput_metrics tx; }; struct selected_chaining { - int policy_id; - enum traffic_type traffic_type; - struct selected_sf *chaining; int chaining_size; - int chaining_index; + int chaining_used; }; // return NULL : error @@ -115,8 +120,7 @@ void selected_chaining_destory(struct selected_chaining *chaining); void selected_chaining_dump(struct selected_chaining *chaining); void selected_chaining_bref(struct selected_chaining *chaining); -// return value need be free by selected_chaining_destory() -struct selected_chaining *policy_enforce_select_chaining(struct policy_enforcer *enforcer, struct raw_pkt_parser *parser, int policy_id, int dir_is_internal); +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); #ifdef __cpluscplus } diff --git a/platform/include/sce.h b/platform/include/sce.h new file mode 100644 index 0000000..78556ce --- /dev/null +++ b/platform/include/sce.h @@ -0,0 +1,108 @@ +#ifndef _SCE_H +#define _SCE_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include "utils.h" +#include "policy.h" +#include "packet_io.h" +#include "session_table.h" + +/****************************************************************************** + * Struct For Global + ******************************************************************************/ + +struct global_metrics +{ + struct throughput_metrics dev_endpoint_rx; // 累计值 + struct throughput_metrics dev_endpoint_tx; // 累计值 + struct throughput_metrics dev_endpoint_err_drop; // 累计值 + + struct throughput_metrics dev_nf_interface_rx; // 累计值 + struct throughput_metrics dev_nf_interface_tx; // 累计值 + struct throughput_metrics dev_nf_interface_err_bypass; // 累计值 + + struct throughput_metrics hit_block_policy; // 累计值 + struct throughput_metrics hit_bypass_policy; // 累计值 + + uint64_t session_nums; // 瞬时值 +}; + +struct global_metrics *global_metrics_create(); +void global_metrics_destory(struct global_metrics *metrics); +void global_metrics_dump(struct global_metrics *metrics); + +/****************************************************************************** + * Struct For Thread + ******************************************************************************/ + +struct thread_ctx +{ + pthread_t tid; + int thread_index; + struct session_table *session_table; + + struct packet_io *ref_io; + struct global_metrics *ref_metrics; + struct policy_enforcer *ref_enforcer; +}; + +/****************************************************************************** + * Struct For Session + ******************************************************************************/ + +struct packet_info +{ + int dir_is_e2i; + struct addr_tuple4 tuple4; + char *addr_string; + + char *header_data; + int header_len; +}; + +struct session_ctx +{ + struct fixed_num_array policy_ids; + uint64_t session_id; + + char raw_pkt_i2e_route_ctx[64]; + char raw_pkt_e2i_route_ctx[64]; + + struct sids raw_pkt_i2e_sids; + struct sids raw_pkt_e2i_sids; + + // depending on first control packet + struct packet_info first_ctrl_pkt; + struct selected_chaining *chaining; +}; + +struct session_ctx *session_ctx_new(); +void session_ctx_free(struct session_ctx *ctx); + +/****************************************************************************** + * Struct For SCE + ******************************************************************************/ + +struct sce_ctx +{ + int firewall_sids; + int nr_worker_threads; + + struct packet_io *io; + struct global_metrics *metrics; + struct policy_enforcer *enforcer; + struct thread_ctx work_threads[128]; +}; + +struct sce_ctx *sce_ctx_create(const char *profile); +void sce_ctx_destory(struct sce_ctx *ctx); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/platform/src/main.cpp b/platform/src/main.cpp index 9f15fa3..ae0fa6d 100644 --- a/platform/src/main.cpp +++ b/platform/src/main.cpp @@ -1,4 +1,83 @@ +#include +#include +#include + +#include "sce.h" +#include "log.h" +#include "utils.h" + +static void *worker_thread_cycle(void *arg) +{ + struct thread_ctx *thread_ctx = (struct thread_ctx *)arg; + struct packet_io *handle = thread_ctx->ref_io; + int n_packet_recv; + + LOG_INFO("%s: worker thread %d running", LOG_TAG_SCE, thread_ctx->thread_index); + + while (1) + { + n_packet_recv = packet_io_polling_nf_interface(handle, thread_ctx->thread_index, thread_ctx); + if (n_packet_recv) + { + LOG_INFO("%s: worker thread %d recv %03d packets from nf_interface", LOG_TAG_SCE, thread_ctx->thread_index, n_packet_recv); + } + + n_packet_recv = packet_io_polling_endpoint(handle, thread_ctx->thread_index, thread_ctx); + if (n_packet_recv) + { + LOG_INFO("%s: worker thread %d recv %03d packets from endpoint", LOG_TAG_SCE, thread_ctx->thread_index, n_packet_recv); + } + + // TODO reset session_table + } + + LOG_ERROR("%s: worker thread %d exiting", LOG_TAG_SCE, thread_ctx->thread_index); + return (void *)NULL; +} + int main(int argc, char **argv) { + const char *profile = "./conf/sce.conf"; + + struct sce_ctx *ctx = sce_ctx_create(profile); + if (ctx == NULL) + { + return -1; + } + + for (int i = 0; i < ctx->nr_worker_threads; i++) + { + ctx->work_threads[i].tid = 0; + ctx->work_threads[i].thread_index = i; + ctx->work_threads[i].session_table = session_table_create(); + ctx->work_threads[i].ref_io = ctx->io; + ctx->work_threads[i].ref_metrics = ctx->metrics; + ctx->work_threads[i].ref_enforcer = ctx->enforcer; + } + + for (int i = 0; i < ctx->nr_worker_threads; i++) + { + struct thread_ctx *thread_ctx = &ctx->work_threads[i]; + if (pthread_create(&thread_ctx->tid, NULL, worker_thread_cycle, (void *)thread_ctx) < 0) + { + LOG_ERROR("%s: unable to create worker thread %d, error %d: %s", LOG_TAG_SCE, i, errno, strerror(errno)); + goto error_out; + } + } + + while (1) + { + sleep(20); + global_metrics_dump(ctx->metrics); + } + +error_out: + for (int i = 0; i < ctx->nr_worker_threads; i++) + { + struct thread_ctx *thread_ctx = &ctx->work_threads[i]; + session_table_destory(thread_ctx->session_table); + } + sce_ctx_destory(ctx); + return 0; -} \ No newline at end of file +} diff --git a/platform/src/packet_io.cpp b/platform/src/packet_io.cpp new file mode 100644 index 0000000..e35fc73 --- /dev/null +++ b/platform/src/packet_io.cpp @@ -0,0 +1,1203 @@ +#include +#include +#include +#include + +#include +#include + +#include "log.h" +#include "sce.h" +#include "g_vxlan.h" +#include "ctrl_packet.h" + +/* + * add: vxlan_hdr + * del: marsio_buff_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 + ******************************************************************************/ + +#define RX_BURST_MAX 128 + +struct config +{ + int bypass_all_traffic; + int rx_burst_max; + char app_symbol[256]; + char dev_endpoint[256]; + char dev_nf_interface[256]; + + char default_src_ip[16]; + char default_dst_ip[16]; + char default_src_mac[32]; + char default_dst_mac[32]; +}; + +struct device +{ + struct mr_vdev *mr_dev; + struct mr_sendpath *mr_path; +}; + +struct packet_io +{ + int thread_num; + struct mr_instance *instance; + struct device dev_nf_interface; + struct device dev_endpoint; + struct config config; +}; + +enum raw_pkt_action +{ + RAW_PKT_ERR_BYPASS, + RAW_PKT_HIT_BYPASS, + RAW_PKT_HIT_BLOCK, + RAW_PKT_HIT_FORWARD, +}; + +enum inject_pkt_action +{ + INJT_PKT_ERR_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; + + int l7_offset; // only control packet set l7_offset + int traffic_is_decrypted; // only raw packet set traffic_is_decrypted + + struct sids sids; + char route_ctx[64]; +}; + +/****************************************************************************** + * API Declaration + ******************************************************************************/ + +struct packet_io *packet_io_create(const char *profile, int thread_num); +void packet_io_destory(struct packet_io *handle); + +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); + +static int packet_io_config(const char *profile, struct config *config); + +// 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); + +// 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_FORWARD +static enum raw_pkt_action handle_raw_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx); +// return : INJT_PKT_ERR_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); + +// return 0 : success +// return -1 : error +static int forward_packet_to_sf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, int chain_index, int thread_seq, void *ctx); +// return 0 : success +// return -1 : error +static int forward_packet_to_nf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, int chain_index, int thread_seq, void *ct); +static void forward_all_nf_packet_to_sf(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx); +static void forward_all_sf_packet_to_nf(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx); + +// 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); + +static void session_value_free_cb(void *ctx); + +/****************************************************************************** + * API Definition + ******************************************************************************/ + +struct packet_io *packet_io_create(const char *profile, int thread_num) +{ + int opt = 1; + struct packet_io *handle = (struct packet_io *)calloc(1, sizeof(struct packet_io)); + assert(handle != NULL); + handle->thread_num = thread_num; + + if (packet_io_config(profile, &(handle->config)) != 0) + { + goto error_out; + } + + handle->instance = marsio_create(); + if (handle->instance == NULL) + { + LOG_ERROR("%s: unable to create marsio instance", LOG_TAG_PKTIO); + goto error_out; + } + + if (marsio_option_set(handle->instance, MARSIO_OPT_EXIT_WHEN_ERR, &opt, sizeof(opt)) != 0) + { + LOG_ERROR("%s: unable to set MARSIO_OPT_EXIT_WHEN_ERR option for marsio instance", LOG_TAG_PKTIO); + goto error_out; + } + + if (marsio_init(handle->instance, handle->config.app_symbol) != 0) + { + LOG_ERROR("%s: unable to initialize marsio instance", LOG_TAG_PKTIO); + 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) + { + LOG_ERROR("%s: unable to open device %s", LOG_TAG_PKTIO, handle->config.dev_nf_interface); + goto error_out; + } + + handle->dev_nf_interface.mr_path = marsio_sendpath_create_by_vdev(handle->dev_nf_interface.mr_dev); + if (handle->dev_nf_interface.mr_path == NULL) + { + LOG_ERROR("%s: unable to create sendpath for device %s", LOG_TAG_PKTIO, handle->config.dev_nf_interface); + 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) + { + LOG_ERROR("%s: unable to open device %s", LOG_TAG_PKTIO, handle->config.dev_endpoint); + goto error_out; + } + + handle->dev_endpoint.mr_path = marsio_sendpath_create_by_vdev(handle->dev_endpoint.mr_dev); + if (handle->dev_endpoint.mr_path == NULL) + { + LOG_ERROR("%s: unable to create sendpath for device %s", LOG_TAG_PKTIO, handle->config.dev_endpoint); + goto error_out; + } + + return handle; + +error_out: + packet_io_destory(handle); + return NULL; +} + +void packet_io_destory(struct packet_io *handle) +{ + if (handle) + { + if (handle->dev_nf_interface.mr_path) + { + marsio_sendpath_destory(handle->dev_nf_interface.mr_path); + handle->dev_nf_interface.mr_path = NULL; + } + + if (handle->dev_nf_interface.mr_dev) + { + marsio_close_device(handle->dev_nf_interface.mr_dev); + handle->dev_nf_interface.mr_dev = NULL; + } + + if (handle->dev_endpoint.mr_path) + { + marsio_sendpath_destory(handle->dev_endpoint.mr_path); + handle->dev_endpoint.mr_path = NULL; + } + + if (handle->dev_endpoint.mr_dev) + { + marsio_close_device(handle->dev_endpoint.mr_dev); + handle->dev_endpoint.mr_dev = NULL; + } + + if (handle->instance) + { + marsio_destory(handle->instance); + handle->instance = NULL; + } + + free(handle); + handle = NULL; + } +} + +// return n_packet_recv +int packet_io_polling_nf_interface(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_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->dev_nf_interface_rx, 1, raw_len); + throughput_metrics_inc(&g_metrics->dev_nf_interface_tx, 1, raw_len); + } + } + + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, rx_buffs, nr_recv); + return nr_recv; + } + else if (handle->config.bypass_all_traffic == 2) + { + for (int j = 0; j < nr_recv; j++) + { + marsio_buff_t *rx_buff = rx_buffs[j]; + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&g_metrics->dev_nf_interface_rx, 1, raw_len); + throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, raw_len); + forward_all_nf_packet_to_sf(handle, rx_buff, thread_seq, ctx); + } + return nr_recv; + } + + for (int j = 0; j < nr_recv; j++) + { + marsio_buff_t *rx_buff = rx_buffs[j]; + if (marsio_buff_is_ctrlbuf(rx_buff)) + { + handle_control_packet(handle, rx_buff, thread_seq, ctx); + // all control packet need bypass + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); + } + else + { + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&g_metrics->dev_nf_interface_rx, 1, raw_len); + enum raw_pkt_action action = handle_raw_packet(handle, rx_buff, thread_seq, ctx); + switch (action) + { + case RAW_PKT_ERR_BYPASS: + throughput_metrics_inc(&g_metrics->dev_nf_interface_err_bypass, 1, raw_len); + break; + case RAW_PKT_HIT_BYPASS: + throughput_metrics_inc(&g_metrics->hit_bypass_policy, 1, raw_len); + break; + case RAW_PKT_HIT_BLOCK: + throughput_metrics_inc(&g_metrics->hit_block_policy, 1, raw_len); + break; + case RAW_PKT_HIT_FORWARD: + 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); + if (nr_recv <= 0) + { + return 0; + } + + if (handle->config.bypass_all_traffic == 1) + { + 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); + } + + marsio_send_burst(handle->dev_endpoint.mr_path, thread_seq, rx_buffs, nr_recv); + return nr_recv; + } + else if (handle->config.bypass_all_traffic == 2) + { + for (int j = 0; j < nr_recv; j++) + { + marsio_buff_t *rx_buff = rx_buffs[j]; + int raw_len = marsio_buff_datalen(rx_buff); + throughput_metrics_inc(&g_metrics->dev_endpoint_rx, 1, raw_len); + throughput_metrics_inc(&g_metrics->dev_nf_interface_tx, 1, raw_len); + forward_all_sf_packet_to_nf(handle, rx_buff, thread_seq, ctx); + } + 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); + throughput_metrics_inc(&g_metrics->dev_endpoint_rx, 1, data_len); + + enum inject_pkt_action action = handle_inject_packet(handle, rx_buff, thread_seq, ctx); + switch (action) + { + case INJT_PKT_ERR_DROP: + throughput_metrics_inc(&g_metrics->dev_endpoint_err_drop, 1, data_len); + break; + case INJT_PKT_HIT_BLOCK: + throughput_metrics_inc(&g_metrics->hit_block_policy, 1, data_len); + break; + case INJT_PKT_HIT_FWD2SF: // forward to next service function + throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, data_len); + break; + case INJT_PKT_HIT_FWD2NF: // forward to network function + throughput_metrics_inc(&g_metrics->dev_nf_interface_tx, 1, data_len); + break; + } + } + + return nr_recv; +} + +// return -1 : error +// return 0 : success +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", "default_src_ip", config->default_src_ip, sizeof(config->default_src_ip)); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "default_dst_ip", config->default_dst_ip, sizeof(config->default_dst_ip)); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "default_src_mac", config->default_src_mac, sizeof(config->default_src_mac)); + MESA_load_profile_string_nodef(profile, "PACKET_IO", "default_dst_mac", config->default_dst_mac, sizeof(config->default_dst_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->default_src_ip : %s", LOG_TAG_PKTIO, config->default_src_ip); + LOG_DEBUG("%s: PACKET_IO->default_dst_ip : %s", LOG_TAG_PKTIO, config->default_dst_ip); + LOG_DEBUG("%s: PACKET_IO->default_src_mac : %s", LOG_TAG_PKTIO, config->default_src_mac); + LOG_DEBUG("%s: PACKET_IO->default_dst_mac : %s", LOG_TAG_PKTIO, config->default_dst_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_L7_OFFSET + // TODO +#if 0 + if (marsio_buff_get_metadata(rx_buff, MR_L7_OFFSET, &(meta->l7_offset), sizeof(meta->l7_offset)) != 0) + { + LOG_ERROR("%s: unable to get l7_offset from metadata", LOG_TAG_PKTIO); + return -1; + } +#endif + } + 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 + } + + if (marsio_buff_get_metadata(rx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx, sizeof(meta->route_ctx)) != 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 (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; + } + + if (meta->is_ctrl_pkt) + { + // TODO +#if 0 + if (marsio_buff_set_metadata(tx_buff, MR_L7_OFFSET, &(meta->l7_offset), sizeof(meta->l7_offset)) != 0) + { + LOG_ERROR("%s: unable to set l7_offset for metadata", LOG_TAG_PKTIO); + return -1; + } +#endif + } + 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 (strlen(meta->route_ctx)) + { + if (marsio_buff_set_metadata(tx_buff, MR_BUFF_ROUTE_CTX, meta->route_ctx, sizeof(meta->route_ctx)) != 0) + { + LOG_ERROR("%s: unable to set route_ctx for metadata", LOG_TAG_PKTIO); + return -1; + } + } + + if (meta->sids.num) + { + 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; +} + +// 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 metadata meta; + if (packet_io_get_metadata(rx_buff, &meta) == -1) + { + LOG_ERROR("%s: unexpected control packet, unable to get metadata", LOG_TAG_PKTIO); + 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); + 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); + return -1; + } + + switch (ctrl_parser.state) + { + case SESSION_STATE_OPENING: + // when session opening, firewall not send policy id + // return handle_session_opening(&meta, &ctrl_parser, thread_seq, ctx); + break; + case SESSION_STATE_CLONING: + return handle_session_closing(&meta, &ctrl_parser, thread_seq, ctx); + case SESSION_STATE_ACTIVE: + return handle_session_active(&meta, &ctrl_parser, thread_seq, ctx); + case SESSION_STATE_RESETALL: + return handle_session_resetall(&meta, &ctrl_parser, thread_seq, ctx); + } + + return 0; +} + +// return : RAW_PKT_ERR_BYPASS +// return : RAW_PKT_HIT_BYPASS +// return : RAW_PKT_HIT_BLOCK +// reutrn : RAW_PKT_HIT_FORWARD +static enum raw_pkt_action handle_raw_packet(struct packet_io *handle, marsio_buff_t *rx_buff, int thread_seq, void *ctx) +{ + struct thread_ctx *thread = (struct thread_ctx *)ctx; + + 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); + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); + 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); + return RAW_PKT_ERR_BYPASS; + } + + // update sids + struct session_ctx *s_ctx = (struct session_ctx *)node->val_data; + if (meta.dir_is_e2i) + { + sids_write_once(&(s_ctx->raw_pkt_e2i_sids), &(meta.sids)); + if (!strlen(s_ctx->raw_pkt_e2i_route_ctx)) + { + memcpy(s_ctx->raw_pkt_e2i_route_ctx, meta.route_ctx, sizeof(s_ctx->raw_pkt_e2i_route_ctx)); + } + } + else + { + sids_write_once(&(s_ctx->raw_pkt_i2e_sids), &(meta.sids)); + if (!strlen(s_ctx->raw_pkt_i2e_route_ctx)) + { + memcpy(s_ctx->raw_pkt_i2e_route_ctx, meta.route_ctx, sizeof(s_ctx->raw_pkt_i2e_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); + return RAW_PKT_ERR_BYPASS; + } + + for (int i = 0; i < chaining->chaining_size; 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 : %d", + 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, 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: + // BLOCK ALL SF + marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); + 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); + return RAW_PKT_ERR_BYPASS; + } + + if (forward_packet_to_sf(handle, rx_buff, &meta, i + 1, thread_seq, ctx) == 0) + { + throughput_metrics_inc(&node->tx, 1, meta.raw_len); + return RAW_PKT_HIT_FORWARD; + } + 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); + // TODO + marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1); + return RAW_PKT_ERR_BYPASS; + } + default: + continue; + } + } + + // BYPASS ALL SF + LOG_INFO("%s: session %lu %s bypass all service function", 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); + return RAW_PKT_HIT_BYPASS; +} + +// return : INJT_PKT_ERR_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) +{ + struct thread_ctx *thread = (struct thread_ctx *)ctx; + + struct g_vxlan *g_vxlan_hdr = NULL; + 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) + { + 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); + 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 udphdr) - 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 chain_index = g_vxlan_get_chain_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); + 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); + memcpy(meta.route_ctx, s_ctx->raw_pkt_e2i_route_ctx, sizeof(s_ctx->raw_pkt_e2i_route_ctx)); + } + else + { + sids_copy(&meta.sids, &s_ctx->raw_pkt_i2e_sids); + memcpy(meta.route_ctx, s_ctx->raw_pkt_i2e_route_ctx, sizeof(s_ctx->raw_pkt_i2e_route_ctx)); + } + + struct selected_chaining *chaining = s_ctx->chaining; + if (chaining == NULL || chain_index < 1 || chain_index > chaining->chaining_size) + { + 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); + return INJT_PKT_ERR_DROP; + } + + throughput_metrics_inc(&chaining->chaining[chain_index - 1].rx, 1, meta.raw_len); + + for (int i = chain_index; i < chaining->chaining_size; 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 : %d", + 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, 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: + // BLOCK ALL SF + marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); + return INJT_PKT_HIT_BLOCK; + 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); + return INJT_PKT_ERR_DROP; + } + + if (forward_packet_to_sf(handle, rx_buff, &meta, i + 1, thread_seq, ctx) == 0) + { + throughput_metrics_inc(&node->tx, 1, meta.raw_len); + 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); + return INJT_PKT_ERR_DROP; + } + default: + continue; + } + } + + if (chain_index != chaining->chaining_size) + { + 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); + return INJT_PKT_ERR_DROP; + } + + if (forward_packet_to_nf(handle, rx_buff, &meta, -1, thread_seq, ctx) == -1) + { + 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); + return INJT_PKT_ERR_DROP; + } + else + { + return INJT_PKT_HIT_FWD2NF; + } +} + +// return 0 : success +// return -1 : error +static int forward_packet_to_sf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, int chain_index, int thread_seq, void *ctx) +{ + // TODO get dst ip frome policy + // TODO get dst mac by dst ip + marsio_buff_reset(rx_buff); + + struct ethhdr *eth_hdr = (struct ethhdr *)marsio_buff_prepend(rx_buff, sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct g_vxlan)); + struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr)); + struct udphdr *udp_hdr = (struct udphdr *)((char *)ip_hdr + sizeof(struct ip)); + struct g_vxlan *g_vxlan_hdr = (struct g_vxlan *)((char *)udp_hdr + sizeof(struct udphdr)); + + memset(g_vxlan_hdr, 0, sizeof(struct g_vxlan)); + g_vxlan_set_packet_dir(g_vxlan_hdr, meta->dir_is_e2i); + g_vxlan_set_chain_index(g_vxlan_hdr, chain_index); + g_vxlan_set_traffic_type(g_vxlan_hdr, meta->traffic_is_decrypted); + + build_ether_header(eth_hdr, ETH_P_IP, handle->config.default_src_mac, handle->config.default_dst_mac); + build_ip_header(ip_hdr, IPPROTO_UDP, handle->config.default_src_ip, handle->config.default_dst_ip, sizeof(struct udphdr) + 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); + + 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 0; +} + +// return 0 : success +// return -1 : error +static int forward_packet_to_nf(struct packet_io *handle, marsio_buff_t *rx_buff, struct metadata *meta, int chain_index, int thread_seq, void *ct) +{ + marsio_buff_adj(rx_buff, marsio_buff_datalen(rx_buff) - meta->raw_len); + + marsio_buff_reset(rx_buff); + if (packet_io_set_metadata(rx_buff, meta) != 0) + { + return -1; + } + + 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 0; +} + +static void forward_all_nf_packet_to_sf(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 metadata meta; + struct raw_pkt_parser raw_parser; + struct addr_tuple4 inner_tuple4; + struct session_ctx *s_ctx = NULL; + struct session_node *node = NULL; + const void *payload = NULL; + + // get metadata + if (packet_io_get_metadata(rx_buff, &meta) == -1) + { + LOG_ERROR("%s: unexpected raw packet, unable to get metadata, drop !!!", LOG_TAG_PKTIO); + marsio_buff_free(handle->instance, &rx_buff, 1, 0, thread_seq); + return; + } + + // search session id + node = session_table_search_by_id(thread->session_table, meta.session_id); + if (node) + { + goto forward; + } + + // add to session table + raw_packet_parser_init(&raw_parser, meta.session_id, LAYER_TYPE_ALL, 8); + 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); + } + + s_ctx = session_ctx_new(); + 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, &inner_tuple4); + s_ctx->first_ctrl_pkt.addr_string = addr_tuple4_to_str(&inner_tuple4); + + if (meta.dir_is_e2i) + { + sids_write_once(&(s_ctx->raw_pkt_e2i_sids), &(meta.sids)); + if (!strlen(s_ctx->raw_pkt_e2i_route_ctx)) + { + memcpy(s_ctx->raw_pkt_e2i_route_ctx, meta.route_ctx, sizeof(s_ctx->raw_pkt_e2i_route_ctx)); + } + } + else + { + sids_write_once(&(s_ctx->raw_pkt_i2e_sids), &(meta.sids)); + if (!strlen(s_ctx->raw_pkt_i2e_route_ctx)) + { + memcpy(s_ctx->raw_pkt_i2e_route_ctx, meta.route_ctx, sizeof(s_ctx->raw_pkt_i2e_route_ctx)); + } + } + + LOG_INFO("%s: session %lu %s opening", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); + + // TODO only add session + __atomic_fetch_add(&g_metrics->session_nums, 1, __ATOMIC_RELAXED); + session_table_insert(thread->session_table, s_ctx->session_id, &inner_tuple4, s_ctx, session_value_free_cb); + + // forward data +forward: + if (forward_packet_to_sf(handle, rx_buff, &meta, 0, thread_seq, ctx) == 0) + { + LOG_ERROR("%s: processing raw 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); + return; + } +} + +static void forward_all_sf_packet_to_nf(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; + + // vxlan decode + struct g_vxlan *g_vxlan_hdr = NULL; + 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) + { + 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); + return; + } + + 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 udphdr) - 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; + + // get inner tuple4 + 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); + + // search session table + 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); + return; + } + + // add meta data + 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); + memcpy(meta.route_ctx, s_ctx->raw_pkt_e2i_route_ctx, sizeof(s_ctx->raw_pkt_e2i_route_ctx)); + } + else + { + sids_copy(&meta.sids, &s_ctx->raw_pkt_i2e_sids); + memcpy(meta.route_ctx, s_ctx->raw_pkt_i2e_route_ctx, sizeof(s_ctx->raw_pkt_i2e_route_ctx)); + } + + // sendto nf + if (forward_packet_to_nf(handle, rx_buff, &meta, -1, thread_seq, ctx) == -1) + { + 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); + return; + } +} + +// 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(); + 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; + s_ctx->chaining = selected_chaining_create(128); + + 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); + fixed_num_array_add_elem(&s_ctx->policy_ids, new_policy_id); + } + } + + LOG_INFO("%s: session %lu %s opening", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->first_ctrl_pkt.addr_string); + + __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 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); + + // TODO send log to firewall + + __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; + 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); + 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; + + LOG_ERROR("%s: session %lu notification clears all session tables !!!", LOG_TAG_PKTIO, meta->session_id); + + __atomic_fetch_and(&g_metrics->session_nums, 0, __ATOMIC_RELAXED); + + // TODO reset all session_table + + return 0; +} + +static void session_value_free_cb(void *ctx) +{ + struct session_ctx *s_ctx = (struct session_ctx *)ctx; + session_ctx_free(s_ctx); +} \ No newline at end of file diff --git a/platform/src/policy.cpp b/platform/src/policy.cpp index 7c3955a..00cb5c4 100644 --- a/platform/src/policy.cpp +++ b/platform/src/policy.cpp @@ -1103,6 +1103,22 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct sff_param *sf return SESSION_ACTION_BYPASS; } +static void selected_sf_init(struct selected_sf *item) +{ + if (item) + { + item->policy_id = -1; + item->traffic_type = TRAFFIC_TYPE_NONE; + item->sff_profile_id = -1; + item->sff_forward_type = FORWARD_TYPE_NONE; + item->sf_need_skip = 0; + item->sf_profile_id = -1; + item->sf_action = SESSION_ACTION_BYPASS; + item->sf_action_reason = ACTION_BYPASS_DUE_DEFAULT; + memset(&item->sf_connectivity, 0, sizeof(struct connectivity)); + } +} + /****************************************************************************** * Public API ******************************************************************************/ @@ -1298,21 +1314,15 @@ struct selected_chaining *selected_chaining_create(int chaining_size) { struct selected_chaining *chaining = (struct selected_chaining *)calloc(1, sizeof(struct selected_chaining)); assert(chaining); - chaining->policy_id = -1; - chaining->traffic_type = TRAFFIC_TYPE_NONE; - chaining->chaining_index = 0; + 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 *elem = &(chaining->chaining[i]); - elem->sff_profile_id = -1; - elem->sff_forward_type = FORWARD_TYPE_NONE; - elem->sf_profile_id = -1; - elem->sf_action = SESSION_ACTION_BYPASS; - elem->sf_action_reason = ACTION_BYPASS_DUE_DEFAULT; + struct selected_sf *item = &(chaining->chaining[i]); + selected_sf_init(item); } return chaining; @@ -1340,18 +1350,20 @@ void selected_chaining_dump(struct selected_chaining *chaining) return; } - LOG_DEBUG("%s: selected_chaining->policy_id : %d", LOG_TAG_POLICY, chaining->policy_id); - LOG_DEBUG("%s: selected_chaining->traffic_type : %s", LOG_TAG_POLICY, traffic_type_to_string(chaining->traffic_type)); 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_size; i++) + 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)); @@ -1371,48 +1383,43 @@ void selected_chaining_bref(struct selected_chaining *chaining) char buff[4096] = {0}; int buff_used = 0; int buff_size = sizeof(buff); - buff_used += snprintf(buff + buff_used, buff_size - buff_used, "policy_id:%d, chaining_size:%d, ", chaining->policy_id, chaining->chaining_size); - for (int i = 0; i < chaining->chaining_size; i++) + 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]={%s:%d:%d} ", i, session_action_reason_to_string(node->sf_action_reason), node->sff_profile_id, node->sf_profile_id); + 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}, ", 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); } } - LOG_DEBUG("%s: selected_chaining_bref: %s", LOG_TAG_POLICY, buff); + LOG_DEBUG("%s: selected_chaining_bref: %s}", LOG_TAG_POLICY, buff); } -// return NULL: NEED BYPASS ALL SFF -// return !NULL: -struct selected_chaining *policy_enforce_select_chaining(struct policy_enforcer *enforcer, struct raw_pkt_parser *parser, int policy_id, int dir_is_internal) +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) { 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 selected_chaining *chaining = NULL; struct chaining_param *chaining_param = 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, bypass !!!", LOG_TAG_POLICY, policy_id); - // BYPASS ALL SFF - return NULL; + LOG_ERROR("%s: failed to get chaining parameter of policy %d", LOG_TAG_POLICY, policy_id); + return; } LOG_DEBUG("%s: enforce chaining policy %d", LOG_TAG_POLICY, policy_id); - chaining = selected_chaining_create(chaining_param->sff_profile_ids_num); - assert(chaining); - chaining->policy_id = policy_id; - chaining->traffic_type = chaining_param->traffic_type; - - for (int i = 0; i < chaining_param->sff_profile_ids_num; i++) + for (int i = 0; i < chaining_param->sff_profile_ids_num && chaining->chaining_used < chaining->chaining_size; i++) { - struct selected_sf *item = &(chaining->chaining[chaining->chaining_index]); + struct selected_sf *item = &(chaining->chaining[chaining->chaining_used]); + selected_sf_init(item); + + item->policy_id = policy_id; + item->traffic_type = chaining_param->traffic_type; item->sff_profile_id = chaining_param->sff_profile_ids[i]; memset(buffer, 0, sizeof(buffer)); @@ -1423,7 +1430,7 @@ struct selected_chaining *policy_enforce_select_chaining(struct policy_enforcer LOG_ERROR("%s: failed to get sff parameter of profile %d, bypass current sff !!!", LOG_TAG_POLICY, item->sff_profile_id); item->sf_action = SESSION_ACTION_BYPASS; item->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY; - chaining->chaining_index++; + chaining->chaining_used++; continue; } item->sff_forward_type = sff_param->sff_forward_type; @@ -1436,7 +1443,7 @@ struct selected_chaining *policy_enforce_select_chaining(struct policy_enforcer LOG_DEBUG("%s: chaining policy %d -> sff_profile %d, no sf available after filtering by 'nearby & active', bypass current sff !!!", LOG_TAG_POLICY, policy_id, item->sff_profile_id); item->sf_action = SESSION_ACTION_BYPASS; item->sf_action_reason = ACTION_BYPASS_DUE_NO_AVAILABLE_SF; - chaining->chaining_index++; + chaining->chaining_used++; sff_param_free(sff_param); continue; } @@ -1445,7 +1452,7 @@ struct selected_chaining *policy_enforce_select_chaining(struct policy_enforcer item->sf_action = select_sf_by_ldbc(hash_value, sff_param, &array, &(item->sf_profile_id), &(item->sf_action_reason)); if (item->sf_action != SESSION_ACTION_FORWARD) { - chaining->chaining_index++; + chaining->chaining_used++; sff_param_free(sff_param); continue; } @@ -1458,7 +1465,7 @@ struct selected_chaining *policy_enforce_select_chaining(struct policy_enforcer LOG_ERROR("%s: failed to get sf parameter of selected profile %d, bypass current sff !!!", LOG_TAG_POLICY, item->sf_profile_id); item->sf_action = SESSION_ACTION_BYPASS; item->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY; - chaining->chaining_index++; + chaining->chaining_used++; sff_param_free(sff_param); continue; } @@ -1467,13 +1474,27 @@ struct selected_chaining *policy_enforce_select_chaining(struct policy_enforcer 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)); - chaining->chaining_index++; + chaining->chaining_used++; sf_param_free(sf_param); sff_param_free(sff_param); } - chaining_param_free(chaining_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; + } + } + } - return chaining; + chaining_param_free(chaining_param); } diff --git a/platform/src/sce.cpp b/platform/src/sce.cpp new file mode 100644 index 0000000..ffbe06f --- /dev/null +++ b/platform/src/sce.cpp @@ -0,0 +1,133 @@ +#include +#include + +#include "sce.h" +#include "log.h" + +/****************************************************************************** + * global_metrics + ******************************************************************************/ + +struct global_metrics *global_metrics_create() +{ + struct global_metrics *metrics = (struct global_metrics *)calloc(1, sizeof(struct global_metrics)); + assert(metrics == NULL); + + return metrics; +} + +void global_metrics_destory(struct global_metrics *metrics) +{ + if (metrics) + { + free(metrics); + metrics = NULL; + } +} + +void global_metrics_dump(struct global_metrics *metrics) +{ + if (metrics) + { + LOG_INFO("%s: dev_endpoint_rx : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->dev_endpoint_rx.n_pkts, metrics->dev_endpoint_rx.n_bytes); + LOG_INFO("%s: dev_endpoint_tx : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->dev_endpoint_tx.n_pkts, metrics->dev_endpoint_tx.n_bytes); + LOG_INFO("%s: dev_endpoint_err_drop : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->dev_endpoint_err_drop.n_pkts, metrics->dev_endpoint_err_drop.n_bytes); + + LOG_INFO("%s: dev_nf_interface_rx : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->dev_nf_interface_rx.n_pkts, metrics->dev_nf_interface_rx.n_bytes); + LOG_INFO("%s: dev_nf_interface_tx : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->dev_nf_interface_tx.n_pkts, metrics->dev_nf_interface_tx.n_bytes); + LOG_INFO("%s: dev_nf_interface_err_bypass : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->dev_nf_interface_err_bypass.n_pkts, metrics->dev_nf_interface_err_bypass.n_bytes); + + LOG_INFO("%s: hit_block_policy : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->hit_block_policy.n_pkts, metrics->hit_block_policy.n_bytes); + LOG_INFO("%s: hit_bypass_policy : n_pkts : %6lu, n_bytes: %6lu", LOG_TAG_METRICS, metrics->hit_bypass_policy.n_pkts, metrics->hit_bypass_policy.n_bytes); + + LOG_INFO("%s: current_session_num : %6lu", LOG_TAG_METRICS, metrics->session_nums); + } +} + +/****************************************************************************** + * session_ctx + ******************************************************************************/ + +struct session_ctx *session_ctx_new() +{ + struct session_ctx *ctx = (struct session_ctx *)calloc(1, sizeof(struct session_ctx)); + assert(ctx != NULL); + return ctx; +} + +void session_ctx_free(struct session_ctx *ctx) +{ + if (ctx) + { + if (ctx->first_ctrl_pkt.addr_string) + { + free(ctx->first_ctrl_pkt.addr_string); + ctx->first_ctrl_pkt.addr_string = 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; + } +} + +/****************************************************************************** + * sce_ctx + ******************************************************************************/ + +struct sce_ctx *sce_ctx_create(const char *profile) +{ + struct sce_ctx *ctx = (struct sce_ctx *)calloc(1, sizeof(struct sce_ctx)); + + 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); + ctx->nr_worker_threads = MIN(ctx->nr_worker_threads, (int)(sizeof(ctx->work_threads) / sizeof(ctx->work_threads[0]))); + + ctx->io = packet_io_create(profile, ctx->nr_worker_threads); + if (ctx->io == NULL) + { + goto error_out; + } + + ctx->metrics = global_metrics_create(); + if (ctx->metrics == NULL) + { + goto error_out; + } + + ctx->enforcer = policy_enforcer_create("SCE", profile, ctx->nr_worker_threads, NULL); + if (ctx->enforcer == NULL) + { + goto error_out; + } + + return ctx; + +error_out: + sce_ctx_destory(ctx); + return NULL; +} + +void sce_ctx_destory(struct sce_ctx *ctx) +{ + if (ctx) + { + policy_enforcer_destory(ctx->enforcer); + global_metrics_destory(ctx->metrics); + packet_io_destory(ctx->io); + + free(ctx); + ctx = NULL; + } +} diff --git a/platform/test/gtest_policy.cpp b/platform/test/gtest_policy.cpp index f71988c..a150048 100644 --- a/platform/test/gtest_policy.cpp +++ b/platform/test/gtest_policy.cpp @@ -24,9 +24,10 @@ TEST(POLICY, SELECTED_CHAINING_LIFE_CYCLE) TEST(POLICY, POLICY_ENFORCER_LIFE_CYCLE) { - struct raw_pkt_parser *parser = raw_packet_parser_create(LAYER_TYPE_ALL, 8); - EXPECT_TRUE(parser != nullptr); - const void *payload = raw_packet_parser_parse(parser, (const void *)data1, sizeof(data1)); + struct raw_pkt_parser handler; + raw_packet_parser_init(&handler, 0, LAYER_TYPE_ALL, 8); + + const void *payload = raw_packet_parser_parse(&handler, (const void *)data1, sizeof(data1)); EXPECT_TRUE(payload != nullptr); EXPECT_TRUE((char *)payload - (char *)&data1 == 70); @@ -35,16 +36,22 @@ TEST(POLICY, POLICY_ENFORCER_LIFE_CYCLE) EXPECT_TRUE(enforcer != nullptr); EXPECT_TRUE(policy_enforcer_register(enforcer) == 0); - int policy_id = 2; int dir_is_internal = 1; - struct selected_chaining *chaining = policy_enforce_select_chaining(enforcer, parser, policy_id, dir_is_internal); + struct selected_chaining *chaining = selected_chaining_create(64); EXPECT_TRUE(chaining != nullptr); + policy_enforce_select_chaining(chaining, enforcer, &handler, 1, dir_is_internal); + policy_enforce_select_chaining(chaining, enforcer, &handler, 2, dir_is_internal); + policy_enforce_select_chaining(chaining, enforcer, &handler, 11, dir_is_internal); + policy_enforce_select_chaining(chaining, enforcer, &handler, 12, dir_is_internal); selected_chaining_dump(chaining); selected_chaining_bref(chaining); - selected_chaining_destory(chaining); + + printf("Before Sleep\n"); + sleep(15); + printf("After Sleep\n"); + policy_enforcer_destory(enforcer); - raw_packet_parser_destory(parser); } int main(int argc, char **argv) diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index 5bc633f..48c2c46 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -50,4 +50,11 @@ set_property(TARGET MESA_prof_load PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA add_library(maatframe SHARED IMPORTED GLOBAL) set_property(TARGET maatframe PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libmaatframe.so) -set_property(TARGET maatframe PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) \ No newline at end of file +set_property(TARGET maatframe PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) + +set(MRZCPD_LIB_DIR /opt/mrzcpd/lib) +set(MRZCPD_INCLUDE_DIR /opt/mrzcpd/include) + +add_library(mrzcpd SHARED IMPORTED GLOBAL) +set_property(TARGET mrzcpd PROPERTY IMPORTED_LOCATION ${MRZCPD_LIB_DIR}/libmarsio.so) +set_property(TARGET mrzcpd PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MRZCPD_INCLUDE_DIR}) \ No newline at end of file