TSG-13630 tsg-service-chaining-engine使用mrzcpd捕获报文/回注报文

TSG-13685 tsg-service-chaining-engine使用VXLAN封装Steering/Mirroring的Package
This commit is contained in:
luwenpeng
2023-02-10 14:22:40 +08:00
parent 158e4e89e8
commit 737ca3d4be
23 changed files with 2397 additions and 358 deletions

View File

@@ -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)

View File

@@ -0,0 +1,38 @@
#ifndef _CTRL_PACKET_H
#define _CTRL_PACKET_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include <stdint.h>
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

52
common/include/g_vxlan.h Normal file
View File

@@ -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

View File

@@ -54,23 +54,29 @@ enum ldbc_method
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);

View File

@@ -10,6 +10,15 @@ extern "C"
#define LOG_TAG_POLICY "POLICY"
#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

View File

@@ -0,0 +1,15 @@
#include <string.h>
#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;
}

67
common/src/g_vxlan.cpp Normal file
View File

@@ -0,0 +1,67 @@
#include <netinet/udp.h>
#include <netinet/ip.h>
#include <netinet/ether.h>
#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;
}

View File

@@ -12,16 +12,21 @@
#include <linux/ppp_defs.h>
#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);
}

View File

@@ -1,6 +1,7 @@
#include <assert.h>
#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;

View File

@@ -1,9 +1,21 @@
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
#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)
@@ -61,3 +98,177 @@ int fixed_num_array_index_elem(struct fixed_num_array *array, int index)
return array->elems[index];
}
/******************************************************************************
* 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;
}
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -1,5 +1,6 @@
[system]
nr_worker_threads=8
firewall_sids=1001
[maat]
# 0:json 1:redis 2:iris
@@ -19,3 +20,16 @@ foreign_cont_dir=resource/foreign_files
redis_db_idx=0
redis_server=127.0.0.1
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

View File

@@ -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/)

View File

@@ -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

View File

@@ -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
}

108
platform/include/sce.h Normal file
View File

@@ -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

View File

@@ -1,4 +1,83 @@
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#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;
}

1203
platform/src/packet_io.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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);
return chaining;
// 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;
}
}
}
chaining_param_free(chaining_param);
}

133
platform/src/sce.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include <assert.h>
#include <MESA/MESA_prof_load.h>
#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;
}
}

View File

@@ -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)

View File

@@ -51,3 +51,10 @@ 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})
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})