summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author刘学利 <[email protected]>2023-02-28 03:17:18 +0000
committer刘学利 <[email protected]>2023-02-28 03:17:18 +0000
commite9974578ead7c7cb9f0c7e758e24c7e7b9b2aeac (patch)
tree94d23f992619aa3ca8b356a8aba39e09d0aad367
parent35ae368647c22ec75ae7034b6f8c29af4f40351e (diff)
overlay为NF模式下,无条件转发数据包,并携带SID、流ID等
-rw-r--r--include/private/stream_internal.h13
-rw-r--r--include/public/stream_inc/sapp_inject.h1
-rw-r--r--include/public/stream_inc/stream_control.h1
-rw-r--r--include/public/stream_inc/stream_inject.h1
-rw-r--r--src/dealpkt/callapp.c15
-rw-r--r--src/dealpkt/deal_tcp.c5
-rw-r--r--src/dealpkt/deal_udp.c8
-rw-r--r--src/dealpkt/plug_support.c3924
-rw-r--r--src/packet_io/packet_io_marsio.c2745
-rw-r--r--src/packet_io/sapp_inject.c10
-rw-r--r--src/packet_io/sendpacket.c10
11 files changed, 3428 insertions, 3305 deletions
diff --git a/include/private/stream_internal.h b/include/private/stream_internal.h
index eaf736b..4acf232 100644
--- a/include/private/stream_internal.h
+++ b/include/private/stream_internal.h
@@ -81,9 +81,12 @@ typedef struct {
const void *raw_pkt_data; /* ���ϲ�Ӧ�ÿ���ԭʼ��ͷָ��, �п���������Ethernet��, ����low_layer_type�ж�Э������ */
struct timeval raw_pkt_ts; /* ԭʼ������ʱ���, ���ȫΪ0��֧�ִ˹���(��pagģʽ) */
const void *io_lib_pkt_reference; /* ���õײ�I/O���ԭʼ�������ṹ, ����:����marsio��˵, ���ײ��mbuf�ṹ */
- int route_dir;
+ int payload_len; /* ���س��� */
int device_index;/* �ж������ʱ, Ҫ��֤���ĸ������ʹ��ĸ����� */
- int is_overlay_pkt; /* ��ʾ����ʵ��·�е����ݰ�, Ҫ��������ע, ��������������һ������; ����Ҫ���� */
+ char is_overlay_pkt; /* ��ʾ����ʵ��·�е����ݰ�, Ҫ��������ע, ��������������һ������; ����Ҫ���� */
+ char is_send_ctrl_pkt;
+ unsigned char route_dir;
+ unsigned char padding;
unsigned short vlan_flipping_couple[2]; /*2020-09-28 lijia add, in host order, vlan flipping for adev, index0��ʾ�յ���ǰ����vlan_id, index1��ʾԭ��ת����vlan_id */
unsigned char mac_flipping_enable;
char diagnose_error_to_dump; /* ��ij�ִ������ݰ�, ����pkt_dump�洢��udp socket���͸�tcpdump_mesa */
@@ -93,6 +96,7 @@ typedef struct {
struct rawpkt_metadata *meta[2];// ���������metadata, �����ڵ���low_level_sendʱ, ���marsio 4.6����Ҫ����Ϣ.
struct segment_id_list *append_list;
struct segment_id_list *prepend_list;
+ unsigned long long stream_trace_id;
}raw_pkt_t;
enum retained_rawpkt_mark
@@ -191,7 +195,8 @@ struct streaminfo_private
unsigned int hash_slave; /* 2015-12-14 lijia add, ʹ��linux_jhash����ʱ, ����ͬʱ�õ��������ϵ�HASHֵ, ��HASH����ȷ����HASH����SLOTλ��, slave_HASH���ڿ��ٱȽϵ�ַ�Ƿ���� */
unsigned char hash_not_head_times;/* 2015-12-15 lijia add, ��ǰindex����HASH SLOT�ĵ�һλ�Ĵ��� */
unsigned char cur_layer_raw_hdr_len; /* 2017-10-31 lijia add, ��ǰ���ԭʼ����ַ����, ��pppͷ��ѹ��, ԭ���汾�޷��������״̬, ����ʱҲ�޷���֪��ַ������ */
- unsigned char __pad:3;
+ unsigned char __pad:2;
+ unsigned char is_send_ctrl_pkt; /* ��ǰ�����Ƿ�Ϊ���Ʊ��� */
unsigned char packet_io_context:1; /* 2019-09-07 lijia add, for polling entry send packet */
unsigned char stream_close_reason:4; /* 2019-02-14 lijia add, ����TCPʹ��tcpdetail_private��link_state����, ����UDP֮ǰû��, ���pad�����˱��� */
unsigned char gdev_block_timer;
@@ -204,6 +209,8 @@ struct streaminfo_private
unsigned short syn_opt_num;
unsigned short synack_opt_num;
/* ===8 bytes=== */
+
+ unsigned long long stream_trace_id;
struct tcp_option *syn_opt_array;
struct tcp_option *synack_opt_array;
diff --git a/include/public/stream_inc/sapp_inject.h b/include/public/stream_inc/sapp_inject.h
index cbcaab1..3ead848 100644
--- a/include/public/stream_inc/sapp_inject.h
+++ b/include/public/stream_inc/sapp_inject.h
@@ -27,6 +27,7 @@ enum sapp_inject_opt{
*/
int sapp_inject_pkt(struct streaminfo *stream, enum sapp_inject_opt sio, const void *payload, int payload_len, unsigned char snd_routedir);
+int sapp_inject_ctrl_pkt(struct streaminfo *stream, enum sapp_inject_opt sio, const void *payload, int payload_len, unsigned char snd_routedir);
#ifdef __cplusplus
diff --git a/include/public/stream_inc/stream_control.h b/include/public/stream_inc/stream_control.h
index d6bfd9c..9e43c45 100644
--- a/include/public/stream_inc/stream_control.h
+++ b/include/public/stream_inc/stream_control.h
@@ -49,6 +49,7 @@ enum MESA_stream_opt{
MSO_STREAM_TIMED,
MSO_STREAM_APPLEND_SEGMENT_ID_LIST,
MSO_STREAM_PREPLEND_SEGMENT_ID_LIST,
+ MSO_STREAM_SET_DATAMETA_TRACE_ID,
__MSO_MAX,
};
diff --git a/include/public/stream_inc/stream_inject.h b/include/public/stream_inc/stream_inject.h
index c469420..dd72cd4 100644
--- a/include/public/stream_inc/stream_inject.h
+++ b/include/public/stream_inc/stream_inject.h
@@ -134,7 +134,6 @@ int MESA_dir_human_to_link(int human_dir);
*/
int MESA_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len, const void *raw_pkt, UCHAR snd_routedir);
-
/*
���������ܵ�MESA_inject_pkt_feedback����, ����ͬMESA_inject_pkt().
��ʵ�ʷ��͵����ݰ�copy��feedback_buf�ռ���, ������feedback_buf_lenΪʵ�����ݰ�����.
diff --git a/src/dealpkt/callapp.c b/src/dealpkt/callapp.c
index 7b3c4b0..645372f 100644
--- a/src/dealpkt/callapp.c
+++ b/src/dealpkt/callapp.c
@@ -815,7 +815,10 @@ int stream_process_tcp(struct streaminfo *a_tcp, const void *this_iphdr, const v
}
#endif
- a_tcp_pr->packet_io_context = 1;
+ if(raw_pkt!=NULL)
+ {
+ a_tcp_pr->packet_io_context = 1;
+ }
ret = stream_process(a_tcp, this_iphdr, transport_hdr, raw_pkt,g_StreamTcpFunNum, g_StreamTcpFun,apme,popstate, SMART_OFFLOAD_FLAG_TCP);
a_tcp_pr->packet_io_context = 0;
@@ -854,7 +857,10 @@ int stream_process_udp(struct streaminfo *a_udp, const void *this_iphdr, const v
raw_ip_frag_list_stream_attach(a_udp);
#endif
- a_udp_pr->packet_io_context = 1;
+ if(raw_pkt!=NULL)
+ {
+ a_udp_pr->packet_io_context = 1;
+ }
ret = stream_process(a_udp, this_iphdr, transport_hdr, raw_pkt, g_StreamUdpFunNum, g_StreamUdpFun, apme, popstate, SMART_OFFLOAD_FLAG_UDP);
a_udp_pr->packet_io_context = 0;
@@ -902,7 +908,10 @@ int stream_process_tcp_allpkt(struct streaminfo *a_tcp,const void *this_iphdr, c
raw_ip_frag_list_stream_attach(a_tcp);
#endif
- a_tcp_pr->packet_io_context = 1;
+ if(raw_pkt!=NULL)
+ {
+ a_tcp_pr->packet_io_context = 1;
+ }
ret = stream_process(a_tcp, this_iphdr, transport_hdr, raw_pkt, g_StreamTcpAllFunNum, g_StreamTcpAllFun, apme, popstate, SMART_OFFLOAD_FLAG_TCPALL);
a_tcp_pr->packet_io_context = 0;
diff --git a/src/dealpkt/deal_tcp.c b/src/dealpkt/deal_tcp.c
index 56d09da..86e617f 100644
--- a/src/dealpkt/deal_tcp.c
+++ b/src/dealpkt/deal_tcp.c
@@ -1334,7 +1334,6 @@ int tcp_free_stream(struct streamindex *pindex, const void *this_ip_hdr, const v
int pkt_ret = PASS;
tcp_update_close_reason_stat(threadnum, pdetail_pr);
-
plist=&(G_MESA_GLOBAL_STREAM[threadnum]->tcpList[pstream->stream_state]);
/* TODO 1,
@@ -2890,6 +2889,10 @@ static int deal_tcp_stream(struct streamindex *pindex, const void *this_iphdr, s
((raw_pkt_t *)raw_pkt)->prepend_list=pstream_pr->sid_prepend_list;
}
+ if(pstream_pr->stream_trace_id != 0)
+ {
+ ((raw_pkt_t *)raw_pkt)->stream_trace_id=pstream_pr->stream_trace_id;
+ }
/* 2014-10-11 lijia add, Fd������ƽ̨ʵ�� */
if(unlikely(pstream_pr->stream_killed_flag != 0)){
diff --git a/src/dealpkt/deal_udp.c b/src/dealpkt/deal_udp.c
index afb17ff..cdbcab2 100644
--- a/src/dealpkt/deal_udp.c
+++ b/src/dealpkt/deal_udp.c
@@ -662,6 +662,10 @@ int dealipv4udppkt(struct streamindex *pindex, const struct mesa_ip4_hdr * this_
{
((raw_pkt_t *)raw_pkt)->prepend_list = pstream_pr->sid_prepend_list;
}
+ if (pstream_pr->stream_trace_id != 0)
+ {
+ ((raw_pkt_t *)raw_pkt)->stream_trace_id = pstream_pr->stream_trace_id;
+ }
/* 2014-11-15 lijia add, for udp serial kill udp */
if(unlikely(a_index->stream.stream_killed_flag != 0)){
@@ -915,6 +919,10 @@ int dealipv6udppkt(struct streamindex *pindex,const struct mesa_ip6_hdr *a_packe
{
((raw_pkt_t *)raw_pkt)->prepend_list = pstream_pr->sid_prepend_list;
}
+ if (pstream_pr->stream_trace_id != 0)
+ {
+ ((raw_pkt_t *)raw_pkt)->stream_trace_id = pstream_pr->stream_trace_id;
+ }
/* 2014-11-15 lijia add, for udp serial kill udp */
if(unlikely(a_index->stream.stream_killed_flag != 0)){
diff --git a/src/dealpkt/plug_support.c b/src/dealpkt/plug_support.c
index becb683..4ec1bbc 100644
--- a/src/dealpkt/plug_support.c
+++ b/src/dealpkt/plug_support.c
@@ -1,1957 +1,1967 @@
-/*
- ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���,
- ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��,
-*/
-#include "sapp_api.h"
-#include "sapp_private_api.h"
-#include "sapp_declaration.h"
-#include "stream_inc/stream_base.h"
-#include "stream_inc/stream_rawpkt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern int G_TCP_FLOW_STAT_PROJECT_ID ;
-extern int G_UDP_FLOW_STAT_PROJECT_ID ;
-
-
-extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
-#if IOMODE_MARSIO
-extern void * (*ptr_marsio_buff_ctrlzone)(marsio_buff_t *m, uint8_t id);
-#endif
-
-
-struct detain_pkt* MESA_rawpkt_detain(const struct streaminfo *pstream, const void *rawpkt)
-{
- if(pstream == NULL || rawpkt == NULL)return NULL;
-
- raw_pkt_t *p_rawpkt = (raw_pkt_t *)rawpkt;
- assert(p_rawpkt->magic_num == RAW_PKT_MAGIC_NUM);
- if(p_rawpkt->magic_num != RAW_PKT_MAGIC_NUM )return NULL;
-
- if(p_rawpkt->d_pkt)return NULL; // rawpkt can be retained only once
- if(p_rawpkt->drop_current_pkt_flag == 1)return NULL; // rawpkt need to be drop, can not be retained
-
- if(sapp_global_val->config.packet_io.depolyment_mode_bin != DEPOLYMENT_MODE_INLINE)return NULL;
-
- struct detain_pkt *d_pkt = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(struct detain_pkt));
- d_pkt->original = rawpkt;
- memcpy(&d_pkt->replica, p_rawpkt, sizeof(raw_pkt_t));
- d_pkt->replica.append_list=NULL;
- d_pkt->replica.prepend_list=NULL;
- if(p_rawpkt->append_list!= NULL && p_rawpkt->append_list->sz_sidlist > 0)
- {
- d_pkt->replica.append_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist);
- memcpy(d_pkt->replica.append_list->sid_list, p_rawpkt->append_list->sid_list, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist);
- d_pkt->replica.append_list->sz_sidlist = p_rawpkt->append_list->sz_sidlist;
- }
- if(p_rawpkt->prepend_list!= NULL && p_rawpkt->prepend_list->sz_sidlist > 0)
- {
- d_pkt->replica.prepend_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist);
- memcpy(d_pkt->replica.prepend_list->sid_list, p_rawpkt->prepend_list->sid_list, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist);
- d_pkt->replica.prepend_list->sz_sidlist = p_rawpkt->prepend_list->sz_sidlist;
- }
- p_rawpkt->d_pkt = d_pkt;
- d_pkt->tid = pstream->threadnum;
-
- return d_pkt;
-}
-
-static void detain_pkt_mem_free(struct detain_pkt *pkt)
-{
- if(pkt == NULL)return;
- if(pkt->replica.append_list)
- {
- sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.append_list);
- }
- if(pkt->replica.prepend_list)
- {
- sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.prepend_list);
- }
- sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt);
-}
-
-int MESA_detain_pkt_forward(struct detain_pkt *pkt)
-{
- if(pkt->original == NULL) //original packet stack finished, being processed by all plugin;
- {
- if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference)
- {
- dl_io_fun_list.dl_io_forward_rawpkt(&pkt->replica, pkt->tid);
- }
- detain_pkt_mem_free(pkt);
- pkt = NULL;
- }
- else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica;
- {
- if(pkt->mark != RETAIN_RAWPKT)
- {
- return -1; // redundant operation, return abnormal
- }
- pkt->mark = FORWARD_RAWPKT;
- }
- return 0;
-}
-
-void MESA_detain_pkt_free(struct detain_pkt *pkt)
-{
- if(pkt->original == NULL) //original packet stack finished, being processed by all plugin;
- {
- if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference)
- {
- dl_io_fun_list.dl_io_free_rawpkt(&pkt->replica, pkt->tid);
- }
- detain_pkt_mem_free(pkt);
- pkt = NULL;
-
- }
- else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica;
- {
- if(pkt->mark == RETAIN_RAWPKT)
- {
- pkt->mark = FREE_RAWPKT;
- }
- }
-}
-
-int MESA_retain_pkt_update(const raw_pkt_t *p_raw_pkt, int pkt_ret)
-{
- int update_ret = pkt_ret;
-
- assert(p_raw_pkt->magic_num == RAW_PKT_MAGIC_NUM);
- if(p_raw_pkt->magic_num != RAW_PKT_MAGIC_NUM )return pkt_ret;
-
- if (p_raw_pkt->d_pkt != NULL)// have retain operation
- {
- if (p_raw_pkt->d_pkt->mark == RETAIN_RAWPKT) //retain pkt in use
- {
- if (pkt_ret == PASS)
- {
- update_ret = RETAIN;
- }
- if (pkt_ret == DROP)
- {
- p_raw_pkt->d_pkt->replica.io_lib_pkt_reference = NULL;
- p_raw_pkt->d_pkt->replica.__lib_raw_pkt_data = NULL;
- p_raw_pkt->d_pkt->replica.__lib_raw_pkt_len = 0;
- }
- p_raw_pkt->d_pkt->original = NULL;
- }
- else //During the processing of the original package, the retained pkt being called forward or free, so it is directly released
- {
- if (p_raw_pkt->d_pkt->mark == FREE_RAWPKT)
- {
- update_ret = DROP;
- }
- detain_pkt_mem_free(p_raw_pkt->d_pkt);
- }
- }
- return update_ret;
-}
-
-int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value)
-{
- int ret = 0;
- const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt;
-
- if(NULL == voidpkt || NULL == void_value){
- return -1;
- }
-
- if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ��๦�� */
- return -1;
- }
-
- switch(type){
- case RAW_PKT_GET_DATA:
- {
- void **out_value = (void **)void_value;
- *out_value = (char *)rawpkt->raw_pkt_data + rawpkt->overlay_layer_bytes;
- }
- break;
-
- case RAW_PKT_GET_RAW_PKT_TYPE:
- {
- enum addr_type_t *out_value = (enum addr_type_t *)void_value;
- *out_value = rawpkt->low_layer_type;
- }
- break;
-
- case RAW_PKT_GET_TOT_LEN:
- {
- int *out_value = (int *)void_value;
- *out_value = rawpkt->raw_pkt_len - rawpkt->overlay_layer_bytes;
- }
- break;
-
- case RAW_PKT_GET_TIMESTAMP:
- {
- struct timeval *out_value =(struct timeval *)void_value;
- memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval));
- }
- break;
-
- case RAW_PKT_GET_THIS_LAYER_HDR:
- {
- void **out_value = (void **)void_value;
- const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr;
- *out_value = (void *)this_layer_hdr;
- }
- break;
-
- case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN:
- {
- int *out_value = (int *)void_value;
- *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr;
- }
- break;
-
- case RAW_PKT_GET_VIRTUAL_LINK_ID:
- {
- /* from sapp v4.2, there is no mrtunnat module, so not support this option! */
- sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_VIRTUAL_LINK_ID' in sappv4.2 and later!");
- ret = -1;
- }
- break;
-
- case RAW_PKT_GET_REHASH_INDEX:
- {
- /* from sapp v4.2, there is no mrtunnat module, so not support this option! */
- sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_REHASH_INDEX' in sappv4.2 and later!");
- ret = -1;
- }
- break;
-
-
- /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */
- case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC:
- {
- const struct mesa_ethernet_hdr *lowest_ehdr;
-
- if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat
- if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
- if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- }else{
- memcpy(void_value, mr_ctrlzone->g_device_mac, ETH_ALEN);
- }
- }else{
- sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!");
- ret = -1;
- }
- }else{
- lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
- memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN);
- }
- }else{ //from v4.2, without mrtunnat
- lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
- memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN);
- }
- }
- break;
-
- /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */
- case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_DMAC:
- {
- const struct mesa_ethernet_hdr *lowest_ehdr;
-
- if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat
- if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
- if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- }else{
- memcpy(void_value, mr_ctrlzone->l_device_mac, ETH_ALEN);
- }
- }else{
- sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!");
- ret = -1;
- }
- }else{
- lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
- memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN);
- }
- }else{ //from v4.2, without mrtunnat
- lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
- memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN);
- }
- }
- break;
-
- default:
- sapp_runtime_log(RLOG_LV_FATAL, "get_opt_from_rawpkt(): not support option type: %d", type);
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-
-
-static const struct streaminfo_private *offset_to_vxlan_layer(const struct streaminfo_private *pstream_pr)
-{
- while(pstream_pr && (ADDR_TYPE_VXLAN != pstream_pr->stream_public.addr.addrtype)){
- pstream_pr = pstream_pr->pfather_pr;
- }
-
- return pstream_pr;
-}
-
-
-static int get_vxlan_info_from_streaminfo(const struct streaminfo_private *pstream_pr, int type, void *void_value)
-{
- int ret = 0;
- const struct streaminfo_private *vxlan_pstream_pr;
- const raw_pkt_t *rawpkt;
- const inline_vxlan_hdr_t *p_vxlan_hdr;
-
- if(DEPOLYMENT_MODE_INLINE != g_topology_mode_raw){
- sapp_runtime_log(RLOG_LV_INFO, "get_rawpkt_opt_from_streaminfo() error: can't support option type: %d in no inline mode!", type);
- return -1;
- }
-
- vxlan_pstream_pr = offset_to_vxlan_layer(pstream_pr);
- if(NULL == vxlan_pstream_pr){
- sapp_runtime_log(RLOG_LV_FATAL, "get_rawpkt_opt_from_streaminfo() error, stream:%s not found vxlan layer!",
- printaddr(&pstream_pr->stream_public.addr, pstream_pr->stream_public.threadnum));
- return -1;
- }
-
- rawpkt = pstream_pr->raw_pkt;
- p_vxlan_hdr = (inline_vxlan_hdr_t *)((char *)rawpkt->raw_pkt_data + vxlan_pstream_pr->offset_to_raw_pkt_hdr);
-
- switch(type){
- case RAW_PKT_GET_GDEV_IP:
- {
- const struct mesa_ip4_hdr *pip4_hdr;
- const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
- if(NULL == carry_vxlan_ip_layer){
- return -1;
- }
-
- pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
- int *out_value = (int *)void_value;
- *out_value = pip4_hdr->ip_src.s_addr;
- }
- break;
-
- case RAW_PKT_GET_VXLAN_LOCAL_IP:
- {
- const struct mesa_ip4_hdr *pip4_hdr;
- const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
- if(NULL == carry_vxlan_ip_layer){
- return -1;
- }
-
- pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
- int *out_value = (int *)void_value;
- *out_value = pip4_hdr->ip_dst.s_addr;
- }
- break;
-
- case RAW_PKT_GET_VXLAN_ID:
- {
- int *out_value = (int *)void_value;
- *out_value = htonl((int)p_vxlan_hdr->link_id);
- }
- break;
-
- case RAW_PKT_GET_VXLAN_VPNID:
- {
- int local_tmp_vpn_id;
- local_tmp_vpn_id = ((int)p_vxlan_hdr->vlan_id_half_high << 4) | (int)p_vxlan_hdr->vlan_id_half_low;
- int *out_value = (int *)void_value;
- *out_value = htonl(local_tmp_vpn_id);
- }
- break;
-
- case RAW_PKT_GET_VXLAN_SPORT:
- {
- const struct mesa_ip4_hdr *pip4_hdr;
- const struct mesa_udp_hdr *pudp_hdr;
- const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
- if(NULL == carry_vxlan_ip_layer){
- return -1;
- }
-
- pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
- pudp_hdr = (struct mesa_udp_hdr *)((char *)pip4_hdr + pip4_hdr->ip_hl*4);
- unsigned short *out_value = (unsigned short *)void_value;
- *out_value = pudp_hdr->uh_sport; /* ���հ��ĽǶ�����, src port��inline�豸��sport */
- }
- break;
-
- case RAW_PKT_GET_VXLAN_ENCAP_TYPE:
- {
- char *out_value = (char *)void_value;
- *out_value = p_vxlan_hdr->link_layer_type;
- }
- break;
-
- case RAW_PKT_GET_VXLAN_LINK_DIR:
- {
- char *out_value = (char *)void_value;
- *out_value = p_vxlan_hdr->dir;
- }
- break;
-
- /* ���հ��ĽǶ�����, src host��inline�豸��mac */
- case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC:
- {
- const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
- memcpy(void_value, p_eth_hdr->ether_shost, ETH_ALEN);
- }
- break;
-
- /* ���հ��ĽǶ�����, dst host�DZ�����mac */
- case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC:
- {
- const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
- memcpy(void_value, p_eth_hdr->ether_dhost, ETH_ALEN);
- }
- break;
- }
-
- return ret;
-}
-
-const void *get_rawpkt_from_streaminfo(const struct streaminfo *pstream)
-{
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- if(pstream_pr->packet_io_context != 0)
- {
- return pstream_pr->raw_pkt;
- }
- return NULL;
-}
-
-int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value)
-{
- int ret = -1;
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
-
- if(NULL == out_value){
- return -1;
- }
-
- if((RAW_PKT_GET_DATA == type)
- && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){
- const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream);
- if(NULL == list_tmp){
- ret = -1;
- }else{
- const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value;
- *out_list = list_tmp;
- ret = 1;
- }
- return ret;
- }
-
- /* sappv4.2֮��, û��mrtunnat, �޷���ctrlzone��ȡ��Щvxlan��ص�ֵ, Ҫ��streaminfo->pfatherƫ�ƻ�ȡ */
- switch(type){
- case RAW_PKT_GET_GDEV_IP:
- case RAW_PKT_GET_VXLAN_ID:
- case RAW_PKT_GET_VXLAN_SPORT:
- case RAW_PKT_GET_VXLAN_ENCAP_TYPE:
- case RAW_PKT_GET_VXLAN_LINK_DIR:
- case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC:
- case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC:
- case RAW_PKT_GET_VXLAN_VPNID:
- case RAW_PKT_GET_VXLAN_LOCAL_IP:
- return get_vxlan_info_from_streaminfo(pstream_pr, type, out_value);
- break;
- }
-
- return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value);
-}
-
-/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/
-const char *printaddr (const struct layer_addr *paddrinfo,int threadindex)
-{
- static char maxbuf[MAX_THREAD_NUM][128];
- char *buf=(char*)maxbuf[threadindex];
- char ip_str[INET6_ADDRSTRLEN];
- struct stream_tuple4_v4 *paddr;
- struct stream_tuple4_v6 *paddr6;
-
- if(NULL == paddrinfo){
- return NULL;
- }
-
- switch(paddrinfo->addrtype){
- case ADDR_TYPE_IPV4:
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,64);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strncpy (buf, ip_str, 64);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
- //strcat (buf, int_ntoa (paddr->daddr));
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
- }
- break;
-
- case ADDR_TYPE_IPV6:
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strncpy (buf, ip_str, 64);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
- }
- break;
-
- case __ADDR_TYPE_IP_PAIR_V4:
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,128);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strncpy (buf, ip_str, 64);
- strcat (buf, ">");
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- }
- break;
-
- case __ADDR_TYPE_IP_PAIR_V6:
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strncpy (buf, ip_str, 64);
- strcat (buf, ">");
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- }
- break;
-
- default:
- {
- return (const char *)"Not support layer type";
- }
- break;
- }
-
- return buf;
-}
-
-/*
- This is a reentrant version of printaddr(),
- Convert tuple4 to string store in out_buf.
- Format: 10.0.0.1, 1234->10.0.0.2,5678.
-*/
-const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len)
-{
- char maxbuf[128];
- char *buf=maxbuf;
- char ip_str[INET6_ADDRSTRLEN];
- int addr_str_len;
- struct stream_tuple4_v4 *paddr;
- struct stream_tuple4_v6 *paddr6;
-
- if((NULL == paddrinfo) || (NULL == out_buf)){
- return "invalid args";
- }
-
- if(paddrinfo->addrtype==ADDR_TYPE_IPV4)
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,128);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strncpy (buf, ip_str, 64);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
- //strcat (buf, int_ntoa (paddr->daddr));
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
- }
- //to addjust
- else if(paddrinfo->addrtype==ADDR_TYPE_IPV6)
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strncpy (buf, ip_str,64);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
- }
- else
- {
- return (const char *)"Not support layer type";
- }
-
- addr_str_len = strlen(buf) + 1; /* add EOF */
- if(addr_str_len > out_buf_len){
- return (const char *)"buf len not enough";
- }
-
- memcpy(out_buf, buf, addr_str_len);
-
- return out_buf;
-}
-
-
-struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info)
-{
- void *addr_value;
- struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr));
- addr_value = malloc(stack_info->addrlen);
-
- memcpy(heap_addr, stack_info, sizeof(struct layer_addr));
- memcpy(addr_value, stack_info->paddr, stack_info->addrlen);
- heap_addr->paddr = addr_value;
-
- return heap_addr;
-}
-
-void layer_addr_free(struct layer_addr *paddrinfo)
-{
- free(paddrinfo->paddr);
- free(paddrinfo);
-}
-
-int get_thread_count(void)
-{
- return g_packet_io_thread_num;
-}
-
-/*
- ctype:
- 'c':count;
- 'l':length;
-*/
-static inline unsigned long long __get_stream_opt_traffic_raw(int cltype, int iotype, struct streaminfo_private *pstream_pr)
-{
- unsigned long long tval;
- struct streaminfo *pstream = &pstream_pr->stream_public;
-
- if('c' == cltype){ /* count */
- if('i' == iotype){ /* inbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->serverpktnum;
- }else{
- tval = pstream->pudpdetail->serverpktnum;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->clientpktnum;
- }else{
- tval = pstream->pudpdetail->clientpktnum;
- }
- }
- }else{ /* outbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->clientpktnum;
- }else{
- tval = pstream->pudpdetail->clientpktnum;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->serverpktnum;
- }else{
- tval = pstream->pudpdetail->serverpktnum;
- }
- }
- }
- }else{/* length */
- if('i' == iotype){ /* inbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw;
- }else{
- tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw;
- }else{
- tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw;
- }
- }
- }else{ /* outbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw;
- }else{
- tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw;
- }else{
- tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw;
- }
- }
- }
- }
-
- return tval;
-}
-
-
-
-/*
- ctype:
- 'c':count;
- 'l':length;
-*/
-static inline unsigned long long __get_stream_opt_traffic(int cltype, int iotype, struct streaminfo_private *pstream_pr)
-{
- unsigned long long tval;
- struct streaminfo *pstream = &pstream_pr->stream_public;
-
- if('c' == cltype){ /* count */
- if('i' == iotype){ /* inbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->serverpktnum;
- }else{
- tval = pstream->pudpdetail->serverpktnum;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->clientpktnum;
- }else{
- tval = pstream->pudpdetail->clientpktnum;
- }
- }
- }else{ /* outbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->clientpktnum;
- }else{
- tval = pstream->pudpdetail->clientpktnum;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->serverpktnum;
- }else{
- tval = pstream->pudpdetail->serverpktnum;
- }
- }
- }
- }else{/* length */
- if('i' == iotype){ /* inbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->serverbytes;
- }else{
- tval = pstream->pudpdetail->serverbytes;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->clientbytes;
- }else{
- tval = pstream->pudpdetail->clientbytes;
- }
- }
- }else{ /* outbound */
- if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->clientbytes;
- }else{
- tval = pstream->pudpdetail->clientbytes;
- }
- }else{
- if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
- tval = pstream->ptcpdetail->serverbytes;
- }else{
- tval = pstream->pudpdetail->serverbytes;
- }
- }
- }
- }
-
- return tval;
-}
-
-
-int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len)
-{
- int ret = -1;
-
- if((NULL == opt_val) || (opt_val_len <= 0)){
- return -1;
- }
-
- switch((int)opt){
- case (int)MSO_MAX_UNORDER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- if(opt_val_len != sizeof(struct max_unorder_opt)){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val;
- ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val);
- }
- break;
-
- case (int)MSO_NEED_ACK:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned char nack = *((unsigned char *)opt_val);
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->needackflag = nack;
- ret = 0;
- }
- break;
-
- case (int)MSO_TAKEOVER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() STREAM_TYPE_TCP error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- int takeover = *((int *)opt_val);
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->takeoverflag = takeover;
- ret = 0;
- }
- break;
-
- case (int)MSO_TIMEOUT:
- {
- if(sizeof(short) != opt_val_len){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned short tmout = *((unsigned short *)opt_val);
- ret = stream_set_single_stream_timeout(pstream, tmout);
- }
- break;
-
- case (int)MSO_IGNORE_RST_FIN:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_IGNORE_RST_FIN error: stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned char igrstfin = *((unsigned char *)opt_val);
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->ignore_rst_fin = igrstfin;
- ret = 0;
- }
- break;
-
- case MSO_TCPALL_VALID_AFTER_KILL:
- {
-#if 0
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error: stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char tcpall_valid = *((unsigned char *)opt_val);
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->tcpall_valid_after_kill = (tcpall_valid == 1 ? 1 : 0);
- ret = 0;
-#else
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCPALL_VALID_AFTER_KILL error: this option is obsoleted!\n", printaddr(&pstream->addr, pstream->threadnum));
-#endif
- }
- break;
-
- case MSO_DROP_STREAM:
- {
- int drop_flag = *((int *)opt_val);
- if(STREAM_TYPE_TCP == pstream->type){
- struct tcpdetail_private *tcp_pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- tcp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0);
- ret = 0;
- }else if(STREAM_TYPE_UDP == pstream->type){
- struct udpdetail_private *udp_pdetail_pr=(struct udpdetail_private*)(pstream->pdetail);
- udp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0);
- ret = 0;
- }else{
- sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_set_stream_opt() MSO_DROP_STREAM error: stream type is not tcp or udp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- }
- }
- break;
-
- case MSO_TCP_RST_REMEDY:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCP_RST_REMEDY error: stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- int remedy_flag = *((int *)opt_val);
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->auto_remedy_flag = (remedy_flag != 0 ? 1:0);
- ret = 0;
- }
- break;
-
- case MSO_DROP_CURRENT_PKT:
- {
- struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream;
- raw_pkt_t *raw_pkt = (raw_pkt_t *)pstream_pr->raw_pkt;
- int drop_value = *((int *)opt_val);
- if(raw_pkt){
- raw_pkt->drop_current_pkt_flag = drop_value;
- }else{
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_DROP_CURRENT_PKT error: current pkt is NULL!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- }
- }
- break;
- case MSO_STREAM_TIMED:
- {
- if(sizeof(int) != opt_val_len){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned int set_timer_s = *((unsigned short *)opt_val);
- struct stream_list *lru_list_root;
- struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
- StreamFunInfo *funinfo = (StreamFunInfo *)pstream_pr->cur_plugin_cb_func;
- funinfo->pstream = pstream;
- funinfo->set_timer_s = set_timer_s;
- if(false == timeout_pending(&funinfo->timeout))
- {
- timeout_init(&funinfo->timeout, TIMEOUT_ABS);
- G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer_cnt+=1;
- }
- timeouts_add(G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer, &funinfo->timeout, set_timer_s+g_CurrentTime);
- ret = 0;
- }
- break;
- case MSO_STREAM_APPLEND_SEGMENT_ID_LIST:
- {
- if(sizeof(struct segment_id_list) != opt_val_len){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val;
- struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
- if(pstream_pr->sid_append_list == NULL)
- {
- if(set_sid_list->sz_sidlist > 0)
- {
- pstream_pr->sid_append_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list));
- memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
- pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist;
- }
- }
- else
- {
- if(set_sid_list->sz_sidlist > 0)
- {
- memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
- pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist;
- }
- else
- {
- memset(pstream_pr->sid_append_list, 0, sizeof(struct segment_id_list));
- }
- }
- ret = 0;
- }
- break;
- case MSO_STREAM_PREPLEND_SEGMENT_ID_LIST:
- {
- if(sizeof(struct segment_id_list) != opt_val_len){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val;
- struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
- if(pstream_pr->sid_prepend_list == NULL)
- {
- if(set_sid_list->sz_sidlist > 0)
- {
- pstream_pr->sid_prepend_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list));
- memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
- pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist;
- }
- }
- else
- {
- if(set_sid_list->sz_sidlist > 0)
- {
- memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
- pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist;
- }
- else
- {
- memset(pstream_pr->sid_prepend_list, 0, sizeof(struct segment_id_list));
- }
- }
- ret = 0;
- }
- break;
- default:
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() error: unsupport MESA_stream_opt type:%d!\n", printaddr(&pstream->addr, pstream->threadnum), (int)opt);
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-
-static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
-{
- struct max_unorder_opt out_val;
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
- UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0;
-
- memset(&out_val, 0, sizeof(struct max_unorder_opt));
- if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){
- out_uorder_C2S = pdetail_pr->pserver->maxunorder;
- out_val.stream_dir |= DIR_C2S;
- }
-
- if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){
- out_uorder_S2C = pdetail_pr->pclient->maxunorder;
- out_val.stream_dir |= DIR_S2C;
- }
-
- out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C;
-
- memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt));
-
- *opt_val_len = sizeof(struct max_unorder_opt);
-
- return 0;
-}
-
-
-static void sapp_mac_addr_to_long(const unsigned char *mac_addr, unsigned long long *smac_integer_type)
-{
- int i;
- char *ptr = (char *)smac_integer_type;
-
- ptr += 5; /* ָ��long long �ĵ�6���ֽ� */
-
- for(i = 0; i < 6; i++){
- *ptr-- = *mac_addr++; /* �������ݰ���mac�����λ, copy��long long���������λ(��ȥ���2���ֽں�) */
- }
-}
-
-static int sapp_get_vxlan_info_from_streaminfo(const struct streaminfo *pstream, struct vxlan_info *vxinfo)
-{
-#define GDEV_SMAC_MASK_ENCAP_TYPE (0x00000000000F0000)
-#define GDEV_SMAC_MASK_ENTRANCE_ID (0x0000000000007C00)
-#define GDEV_SMAC_MASK_DEV_ID (0x00000000000003F0)
-#define GDEV_SMAC_MASK_LINK_ID (0x000000000000000E)
-#define GDEV_SMAC_MASK_LINK_DIR (0x0000000000000001)
-
- int i;
- const struct streaminfo *mim_stream = pstream->pfather;
- const struct layer_addr_mac_in_mac *mim_addr;
- const struct layer_addr_mac *mac_addr;
- unsigned char *ptr;
- unsigned long long smac_integer_type; /* 48bit macת��Ϊ64bit�ij��������ִ洢, ���ڲ��� */
-
- while(mim_stream){//���ڶ��mac��ַ�������ֻ�������MAC��ַȡvxlan_info
- if((ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype || ADDR_TYPE_MAC == mim_stream->addr.addrtype) &&
- (mim_stream->pfather == NULL)){
- break;
- }else{
- mim_stream = mim_stream->pfather;
- }
- }
-
- if(NULL == mim_stream){
- return -1;
- }
-
- memset(vxinfo, 0, sizeof(struct vxlan_info));
-
- if (ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
- {
- mim_addr = mim_stream->addr.mimac;
- sapp_mac_addr_to_long(mim_addr->outer_src_mac, &smac_integer_type);
- }
- else
- {
- mac_addr = mim_stream->addr.mac;
- sapp_mac_addr_to_long(mac_addr->src_addr.h_source, &smac_integer_type);
- }
- vxinfo->encap_type = (smac_integer_type & GDEV_SMAC_MASK_ENCAP_TYPE) >> 16;
- vxinfo->entrance_id = (smac_integer_type & GDEV_SMAC_MASK_ENTRANCE_ID) >> 10;
- vxinfo->dev_id = (smac_integer_type & GDEV_SMAC_MASK_DEV_ID) >> 4;
- vxinfo->link_id = (smac_integer_type & GDEV_SMAC_MASK_LINK_ID ) >> 1;
- vxinfo->link_dir = (smac_integer_type & GDEV_SMAC_MASK_LINK_DIR);
-
- if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
- {
- ptr = vxinfo->inner_smac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mim_addr->inner_src_mac[i]);
- }
- vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_smac_hex, mim_addr->inner_src_mac, 6);
-
- ptr = vxinfo->inner_dmac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mim_addr->inner_dst_mac[i]);
- }
- vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_dmac_hex, mim_addr->inner_dst_mac, 6);
- }
- else
- {
- ptr = vxinfo->inner_smac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_source[i]);
- }
- vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_smac_hex, mac_addr->src_addr.h_source, 6);
-
- ptr = vxinfo->inner_dmac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_dest[i]);
- }
- vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_dmac_hex, mac_addr->src_addr.h_dest, 6);
- }
- return 0;
-}
-
-
-static void *MESA_get_stream_plug_pme_from_platform_entry(const StreamFunInfo *plug_pme_head, const void *this_plug_entry)
-{
- void *this_plug_pme = NULL;
-
- while(plug_pme_head){
- if(plug_pme_head->pfun == this_plug_entry){
- this_plug_pme = plug_pme_head->pAppInfo;
- break;
- }
- plug_pme_head = plug_pme_head->next;
- }
-
- return this_plug_pme;
-}
-
-/*
- ���ݲ����ں���������, ��ȡ�����˽�д洢�ռ�ָ��pme.
-*/
-static int MESA_get_stream_plug_pme(const struct streaminfo *pstream, void *opt_val, const int *opt_val_len)
-{
- int ret = 0;
- struct mso_plug_pme *in_arg;
- const struct streaminfo_private *stream_pr;
- struct tcpdetail_private *ptcp_detail_pr;
- struct udpdetail_private *pudp_detail_pr;
-
- const void *this_plug_entry;
- void *plug_pme;
-
- if((NULL == opt_val) || (NULL == opt_val_len)){
- return -1;
- }
-
- if(*opt_val_len != sizeof(struct mso_plug_pme)){
- return -1;
- }
-
- in_arg = (struct mso_plug_pme *)opt_val;
- stream_pr = (struct streaminfo_private *)pstream;
- in_arg->plug_pme = NULL;
-
- this_plug_entry = plugin_get_plug_entry(in_arg->plug_name, in_arg->plug_entry_type);
- if(NULL == this_plug_entry){
- sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, can't get plug:%s entry:%s address",
- printaddr(&pstream->addr, pstream->threadnum), in_arg->plug_name, in_arg->plug_entry_type);
- return -1;
- }
-
- if(STREAM_TYPE_TCP == pstream->type){
- ptcp_detail_pr=(struct tcpdetail_private *)(pstream->pdetail);
- plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->apme, this_plug_entry);
- if(plug_pme != NULL){
- in_arg->plug_pme = plug_pme;
- goto bingo;
- }
- plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->pAllpktpme, this_plug_entry);
- if(plug_pme != NULL){
- in_arg->plug_pme = plug_pme;
- goto bingo;
- }
- }else if(STREAM_TYPE_UDP == pstream->type){
- pudp_detail_pr = (struct udpdetail_private *)(pstream->pdetail);
- plug_pme = MESA_get_stream_plug_pme_from_platform_entry(pudp_detail_pr->apme, this_plug_entry);
- if(plug_pme != NULL){
- in_arg->plug_pme = plug_pme;
- goto bingo;
- }
- }else{
- sapp_runtime_log(RLOG_LV_FATAL, "%s, MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, not support stream type:%d", printaddr(&pstream->addr, pstream->threadnum),pstream->type);
- return -1;
- }
-
- if(NULL == in_arg->plug_pme){
- ret = -1;
- }
-
-bingo:
-
- return ret;
-}
-
-
-static int MESA_get_stream_dup_pkt_stat(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
-{
- const struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream;
- int *res_val = (int *)opt_val;
- int ret = 0;
-
- if((0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_all_inject)
- && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_tcp)
- && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_udp)){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, config DUPLICATE_PKT is not enable",
- printaddr(&pstream->addr, pstream->threadnum));
- *res_val = -2;
- return 0;
- }
-
- if(pstream_pr->has_duplicate_pkt != 0){
- *res_val = 1;
- return 0;
- }
-
- /* �������ظ�����⹦��,����û�������ظ��� */
- if(STREAM_TYPE_TCP == pstream->type){
- if(pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */
- *res_val = -2;
- sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt",
- printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum);
- }else{
- *res_val = 0;
- }
- }else if(STREAM_TYPE_UDP == pstream->type){
- if(pstream->pudpdetail->clientpktnum + pstream->pudpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */
- sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt",
- printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum);
- *res_val = -2;
- }else{
- *res_val = 0;
- }
- }else{
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, not support stream type:%d",
- printaddr(&pstream->addr, pstream->threadnum), pstream->type);
- *res_val = -2;
- ret = -1;
- }
-
- return ret;
-}
-
-int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len)
-{
- int ret = 0;
-
- if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){
- return -1;
- }
-
- switch((int)opt){
- case (int)MSO_MAX_UNORDER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){
- sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- *opt_val_len = sizeof(struct max_unorder_opt);
- ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len);
- }
- break;
-
- case (int)MSO_NEED_ACK:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned char *nack = (unsigned char *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *nack = pdetail_pr->needackflag;
- *opt_val_len = sizeof(char);
- }
- break;
-
- case (int)MSO_TAKEOVER:
- {
- if(*opt_val_len < (int)sizeof(int)){
- ret = -1;
- break;
- }
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TAKEOVER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- int *takeover = (int *)opt_val;
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- *takeover = pdetail_pr->takeoverflag;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case (int)MSO_TIMEOUT:
- {
- if(sizeof(short) != *opt_val_len){
- sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned short *tmout = (unsigned short *)opt_val;
- struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
- *tmout = pstream_pr->timeout;
- *opt_val_len = sizeof(short);
- }
- break;
-
- case (int)MSO_IGNORE_RST_FIN:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_IGNORE_RST_FIN error:stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned char *igrstfin = (unsigned char *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *igrstfin = pdetail_pr->ignore_rst_fin;
- }
- break;
-
- case MSO_TCP_CREATE_LINK_MODE:
- {
- struct tcpdetail_private *pdetail_pr;
- UCHAR *out_val = (UCHAR *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TCP_CREATE_LINK_MODE error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
-
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *out_val = pdetail_pr->creat_mod;
- *opt_val_len = sizeof(char);
- }
- break;
-
- case MSO_TCP_ISN_C2S:
- {
- struct tcpdetail_private *pdetail_pr;
- UINT32 *out_val = (UINT32 *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
-
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: stream create mode is not by SYN!\n", printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
- if(0 == pdetail_pr->iserverseq){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: can't get SYN seq!\n", printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
-
- *out_val = pdetail_pr->iserverseq - 1;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case MSO_TCP_ISN_S2C:
- {
- /* TODO 1: �����������ظ�, ���ϲ� */
- struct tcpdetail_private *pdetail_pr;
- UINT32 *out_val = (UINT32 *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: stream create mode is not by SYN!\n",printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
-
- if(0 == pdetail_pr->iclientseq){
- ret = -1;
- if(pstream->dir != DIR_C2S)
- {
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: can't get SYN/ACK seq!\n",printaddr(&pstream->addr, pstream->threadnum));
- }
- break;
- }
-
- *out_val = pdetail_pr->iclientseq - 1;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case MSO_TCP_SYN_OPT:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- struct tcp_option **out_val = (struct tcp_option **)opt_val;
- if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){
- *out_val = pstream_pr->syn_opt_array;
- *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
- ret = 0;
- }else{
- ret = -1;
- }
- }
- break;
-
- case MSO_TCP_SYNACK_OPT:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- struct tcp_option **out_val = (struct tcp_option **)opt_val;
- if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){
- *out_val = pstream_pr->synack_opt_array;
- *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
- ret = 0;
- }else{
- ret = -1;
- }
- }
- break;
-
- case MSO_STREAM_TUNNEL_TYPE:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- unsigned short *out_val = (unsigned short *)opt_val;
- *out_val = pstream_pr->stream_low_layer_tunnel_type;
- ret = 0;
- }
- break;
-
- case MSO_STREAM_UP_LAYER_TUNNEL_TYPE:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- unsigned short *out_val = (unsigned short *)opt_val;
- *out_val = pstream_pr->stream_carry_up_layer_tunnel_type;
- ret = 0;
- }
- break;
-
- case MSO_STREAM_CLOSE_REASON:
- {
- UCHAR *close_reason = (UCHAR *)opt_val;
-
- if(pstream->opstate != OP_STATE_CLOSE){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:has not closed!\n",printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
- if(STREAM_TYPE_TCP == pstream->type){
- const struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *close_reason = pdetail_pr->link_state;
- }else if(STREAM_TYPE_UDP == pstream->type){
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- *close_reason = pstream_pr->stream_close_reason;
- }else{
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:unsupport stream type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), pstream->type);
- }
- }
- break;
-
- case MSO_STREAM_VXLAN_INFO:
- if(DEPOLYMENT_MODE_MIRROR != g_topology_mode_raw){
- sapp_runtime_log(RLOG_LV_INFO, "MESA_get_stream_opt() error: can't support option MSO_STREAM_VXLAN_INFO in no mirror mode!");
- return -1;
- }
- if(*opt_val_len != sizeof(struct vxlan_info)){
- return -1;
- }
- ret = sapp_get_vxlan_info_from_streaminfo(pstream, (struct vxlan_info *)opt_val);
- break;
-
- case MSO_GLOBAL_STREAM_ID:
- {
- const struct streaminfo_private *pstream_pr;
- if(*opt_val_len != sizeof(long long)){
- return -1;
- }
- pstream_pr = (const struct streaminfo_private *)pstream;
- unsigned long long *out_args = (unsigned long long *)opt_val;
- unsigned long long dev_id = *out_args;
- if(dev_id > 4095){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_GLOBAL_STREAM_ID error:invalid dev_id:%llu!\n", printaddr(&pstream->addr, pstream->threadnum), dev_id);
- return -1;
- }
- unsigned long long local_global_id = pstream_pr->global_stream_id;
-
- *out_args = local_global_id | (dev_id << 51);
- ret = 0;
- }
- break;
-
- case MSO_TOTAL_INBOUND_PKT:
- {
- if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned long long *inbound_pkt = (unsigned long long *)opt_val;
- *inbound_pkt = __get_stream_opt_traffic('c', 'i', (struct streaminfo_private *)pstream);
- }
- break;
-
- case MSO_TOTAL_OUTBOUND_PKT:
- {
- if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned long long *outbound_pkt = (unsigned long long *)opt_val;
- *outbound_pkt = __get_stream_opt_traffic('c', 'o', (struct streaminfo_private *)pstream);
- }
- break;
-
- case MSO_TOTAL_INBOUND_BYTE:
- {
- if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned long long *inbound_byte = (unsigned long long *)opt_val;
- *inbound_byte = __get_stream_opt_traffic('l', 'i', (struct streaminfo_private *)pstream);
- }
- break;
-
- case MSO_TOTAL_INBOUND_BYTE_RAW:
- {
- if(STREAM_TYPE_TCP == pstream->type){
- if(G_TCP_FLOW_STAT_PROJECT_ID == -1){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
- }else if(STREAM_TYPE_UDP == pstream->type){
- if(G_UDP_FLOW_STAT_PROJECT_ID == -1){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
- }else{
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
-
- unsigned long long *inbound_byte = (unsigned long long *)opt_val;
- *inbound_byte = __get_stream_opt_traffic_raw('l', 'i', (struct streaminfo_private *)pstream);
- }
- break;
-
-
- case MSO_TOTAL_OUTBOUND_BYTE:
- {
- if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned long long *outbound_byte = (unsigned long long *)opt_val;
- *outbound_byte = __get_stream_opt_traffic('l', 'o', (struct streaminfo_private *)pstream);
- }
- break;
-
- case MSO_TOTAL_OUTBOUND_BYTE_RAW:
- {
- if(STREAM_TYPE_TCP == pstream->type){
- if(G_TCP_FLOW_STAT_PROJECT_ID == -1){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
- }else if(STREAM_TYPE_UDP == pstream->type){
- if(G_UDP_FLOW_STAT_PROJECT_ID == -1){
- ret = -1;
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
- break;
- }
- }else{
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
-
- unsigned long long *outbound_byte = (unsigned long long *)opt_val;
- *outbound_byte = __get_stream_opt_traffic_raw('l', 'o', (struct streaminfo_private *)pstream);
- }
- break;
-
- case MSO_STREAM_CREATE_TIMESTAMP_MS:
- {
- if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type))
- {
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CREATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned long long *timestamp_ms = (unsigned long long *)opt_val;
- *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_create_timestamp_ms;
- }
- break;
- case MSO_STREAM_LASTUPDATE_TIMESTAMP_MS:
- {
- if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type))
- {
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_LASTUPDATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
- ret = -1;
- break;
- }
- unsigned long long *timestamp_ms = (unsigned long long *)opt_val;
- *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_lastupdate_timestamp_ms;
- }
- break;
-
- case MSO_STREAM_PLUG_PME:
- ret = MESA_get_stream_plug_pme(pstream, opt_val, opt_val_len);
- break;
-
- case MSO_HAVE_DUP_PKT:
- ret = MESA_get_stream_dup_pkt_stat(pstream, opt_val, opt_val_len);
- break;
-
- default:
- sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), (int)opt);
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int is_proxy_stream(const struct streaminfo *pstream)
-{
- int ret = 0;
-
- switch(pstream->type){
- case STREAM_TYPE_SOCKS4:
- case STREAM_TYPE_SOCKS5:
- case STREAM_TYPE_HTTP_PROXY:
- case STREAM_TYPE_OPENVPN:
- ret = 1;
- break;
-
- default:
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-
-void set_current_thread_cpu_affinity(int thread_index)
-{
- if(sapp_global_val->config.cpu.bind_mask_array_num != 0){
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- CPU_SET(sapp_global_val->config.cpu.bind_mask_array[thread_index], &cpuset);
- pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
- }
-
- return;
-}
-
-int get_current_thread_cpu_affinity_id(void)
-{
- int i;
- cpu_set_t current_cpu_mask;
-
- CPU_ZERO(&current_cpu_mask);
-
- if(pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &current_cpu_mask) < 0){
- return -1;
- }
-
- int tot_cpu_core = get_nprocs();
- int tot_cpu_set_count = CPU_COUNT(&current_cpu_mask);
- if((tot_cpu_set_count == tot_cpu_core) || (tot_cpu_set_count > 1)){
- /* ȫ����������, ��ʵ����û�а�,
- �����������isolcpus, ���㲻���, CPU_COUNT���ܺ������������,
- ��������1���϶���û�о�ȷ�󶨵�ij������ */
- return -1;
- }
-
- for(i = 0; i <= tot_cpu_core; i++){
- if(CPU_ISSET(i, &current_cpu_mask)){
- break;
- }
- }
-
- return i;
-}
-
-
-
-extern int project_req_terminal_tag_id;
-/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */
-const unsigned char *get_terminal_tag(struct streaminfo *stream)
-{
- unsigned char *terminal_tag;
-
- if(project_req_terminal_tag_id < 0){
- return NULL;
- }
-
- terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id);
-
- return (const unsigned char *)terminal_tag;
-}
-
-int number_is_2powerN(uint n)
-{
- if(n & (n-1)){
- return 0;
- }
-
- return 1;
-}
-
-
-
-void *dictator_malloc(int thread_seq,size_t size)
-{
- /*
- if(malloccount%100000==0)
- {
- printf("malloc=%d,free=%d\n",malloccount,freecount);
- }
- */
-
- if(G_DICTATOR_SW){
-#if USE_MEMPOOL
- return __dictator_malloc(thread_seq, size);
-#endif
- }
-
- return malloc(size);
-}
-void dictator_free(int thread_seq,void *pbuf)
-{
-#if USE_MEMPOOL
- if(G_DICTATOR_SW){
- __dictator_free(thread_seq, pbuf);
- }
- else
-#endif
- {
-#if SAPP_INSECTICIDE
- *((char *)pbuf) = 0xFE;
-#endif
- free(pbuf);
- }
-}
-
-void *dictator_realloc(int thread_seq, void *ptr, size_t size)
-{
-#if USE_MEMPOOL
- if(G_DICTATOR_SW){
- return __dictator_realloc(thread_seq, ptr, size);
- }
-#endif
-
- return realloc(ptr, size);
-}
-
-/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */
-char biz_retval_to_platform(char biz_ret)
-{
- char plat_ret = 0;
-
- if(biz_ret & PROT_STATE_GIVEME){
- plat_ret |= APP_STATE_GIVEME;
- }
-
- if(biz_ret & PROT_STATE_DROPME){
- plat_ret |= APP_STATE_DROPME;
- }
-
- if(biz_ret & PROT_STATE_DROPPKT){
- plat_ret |= APP_STATE_DROPPKT;
- }
-
- return plat_ret;
-}
-
-/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */
-char plat_state_to_biz(char plat_state)
-{
- char biz_ret = SESSION_STATE_CLOSE;
-
- switch(plat_state){
- case OP_STATE_PENDING:
- biz_ret = SESSION_STATE_PENDING;
- break;
-
- case OP_STATE_DATA:
- biz_ret = SESSION_STATE_DATA;
- break;
-
- case OP_STATE_CLOSE:
- biz_ret = SESSION_STATE_CLOSE;
- break;
-
- default:
- break;
- }
-
- return biz_ret;
-}
-
-
-long long sapp_get_cpu_cycle(void)
-{
-#ifdef __x86_64
-#define X86_64_ENV 1
-#endif
-#ifdef __x86_64__
-#define X86_64_ENV 1
-#endif
-
-#ifdef X86_64_ENV
- long long l;
- long long h;
-
- __asm__ volatile("rdtsc" : "=a"(l), "=d"(h));
- return (long long )l | ((long long )h<<32);
-#else
- return 0;
-#endif
-}
-
-void sapp_set_current_state(enum sapp_state_t state)
-{
- sapp_global_val->individual_volatile->current_state = (int)state;
-}
-
-enum sapp_state_t sapp_get_current_state(void)
-{
- return (enum sapp_state_t)sapp_global_val->individual_volatile->current_state;
-}
-
-int sapp_size_of_sapp_global(void)
-{
- return sizeof(sapp_global_t);
-}
-
-
-int sapp_size_of_streaminfo_private(void)
-{
- return sizeof(struct streaminfo_private);
-}
-
-int sapp_size_of_tcpdetail_private(void)
-{
- return sizeof(struct tcpdetail_private);
-}
-
-int sapp_size_of_udpdetail_private(void)
-{
- return sizeof(struct udpdetail_private);
-}
-
-int sapp_size_of_raw_pkt_t(void)
-{
- return sizeof(raw_pkt_t);
-}
-
-
-char *sapp_strdup(const char *raw_s)
-{
- int buflen = strlen(raw_s) + 1; //add EOF
- char *new_s = (char *)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, buflen);
- memcpy(new_s, raw_s, buflen);
-
- return new_s;
-}
-
-int sapp_is_absolute_path(const char *filename)
-{
- if('/' == filename[0]){
- return 1;
- }
-
- return 0;
-}
-
-long long sapp_random(void)
-{
- struct timespec curtime;
-
- clock_gettime(CLOCK_MONOTONIC, &curtime);
-
- return (curtime.tv_nsec * 131) ^ curtime.tv_sec;
-}
-
-int sapp_usleep(int usec)
-{
- struct timespec sleep_time_val;
-
- sleep_time_val.tv_sec = 0;
- sleep_time_val.tv_nsec = usec * 1000;
-
- nanosleep(&sleep_time_val, NULL);
-
- return 0;
-}
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
+/*
+ ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���,
+ ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��,
+*/
+#include "sapp_api.h"
+#include "sapp_private_api.h"
+#include "sapp_declaration.h"
+#include "stream_inc/stream_base.h"
+#include "stream_inc/stream_rawpkt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int G_TCP_FLOW_STAT_PROJECT_ID ;
+extern int G_UDP_FLOW_STAT_PROJECT_ID ;
+
+
+extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
+#if IOMODE_MARSIO
+extern void * (*ptr_marsio_buff_ctrlzone)(marsio_buff_t *m, uint8_t id);
+#endif
+
+
+struct detain_pkt* MESA_rawpkt_detain(const struct streaminfo *pstream, const void *rawpkt)
+{
+ if(pstream == NULL || rawpkt == NULL)return NULL;
+
+ raw_pkt_t *p_rawpkt = (raw_pkt_t *)rawpkt;
+ assert(p_rawpkt->magic_num == RAW_PKT_MAGIC_NUM);
+ if(p_rawpkt->magic_num != RAW_PKT_MAGIC_NUM )return NULL;
+
+ if(p_rawpkt->d_pkt)return NULL; // rawpkt can be retained only once
+ if(p_rawpkt->drop_current_pkt_flag == 1)return NULL; // rawpkt need to be drop, can not be retained
+
+ if(sapp_global_val->config.packet_io.depolyment_mode_bin != DEPOLYMENT_MODE_INLINE)return NULL;
+
+ struct detain_pkt *d_pkt = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(struct detain_pkt));
+ d_pkt->original = rawpkt;
+ memcpy(&d_pkt->replica, p_rawpkt, sizeof(raw_pkt_t));
+ d_pkt->replica.append_list=NULL;
+ d_pkt->replica.prepend_list=NULL;
+ if(p_rawpkt->append_list!= NULL && p_rawpkt->append_list->sz_sidlist > 0)
+ {
+ d_pkt->replica.append_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist);
+ memcpy(d_pkt->replica.append_list->sid_list, p_rawpkt->append_list->sid_list, sizeof(unsigned short)*p_rawpkt->append_list->sz_sidlist);
+ d_pkt->replica.append_list->sz_sidlist = p_rawpkt->append_list->sz_sidlist;
+ }
+ if(p_rawpkt->prepend_list!= NULL && p_rawpkt->prepend_list->sz_sidlist > 0)
+ {
+ d_pkt->replica.prepend_list = sapp_mem_calloc(SAPP_MEM_DYN_DETAIN_PKT, pstream->threadnum, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist);
+ memcpy(d_pkt->replica.prepend_list->sid_list, p_rawpkt->prepend_list->sid_list, sizeof(unsigned short)*p_rawpkt->prepend_list->sz_sidlist);
+ d_pkt->replica.prepend_list->sz_sidlist = p_rawpkt->prepend_list->sz_sidlist;
+ }
+ p_rawpkt->d_pkt = d_pkt;
+ d_pkt->tid = pstream->threadnum;
+
+ return d_pkt;
+}
+
+static void detain_pkt_mem_free(struct detain_pkt *pkt)
+{
+ if(pkt == NULL)return;
+ if(pkt->replica.append_list)
+ {
+ sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.append_list);
+ }
+ if(pkt->replica.prepend_list)
+ {
+ sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt->replica.prepend_list);
+ }
+ sapp_mem_free(SAPP_MEM_DYN_DETAIN_PKT, pkt->tid, pkt);
+}
+
+int MESA_detain_pkt_forward(struct detain_pkt *pkt)
+{
+ if(pkt->original == NULL) //original packet stack finished, being processed by all plugin;
+ {
+ if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference)
+ {
+ dl_io_fun_list.dl_io_forward_rawpkt(&pkt->replica, pkt->tid);
+ }
+ detain_pkt_mem_free(pkt);
+ pkt = NULL;
+ }
+ else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica;
+ {
+ if(pkt->mark != RETAIN_RAWPKT)
+ {
+ return -1; // redundant operation, return abnormal
+ }
+ pkt->mark = FORWARD_RAWPKT;
+ }
+ return 0;
+}
+
+void MESA_detain_pkt_free(struct detain_pkt *pkt)
+{
+ if(pkt->original == NULL) //original packet stack finished, being processed by all plugin;
+ {
+ if(pkt->replica.__lib_raw_pkt_len > 0 && pkt->replica.__lib_raw_pkt_data && pkt->replica.io_lib_pkt_reference)
+ {
+ dl_io_fun_list.dl_io_free_rawpkt(&pkt->replica, pkt->tid);
+ }
+ detain_pkt_mem_free(pkt);
+ pkt = NULL;
+
+ }
+ else //still in original packet stack, need be processed by follow-up plugin, mark operation to replica;
+ {
+ if(pkt->mark == RETAIN_RAWPKT)
+ {
+ pkt->mark = FREE_RAWPKT;
+ }
+ }
+}
+
+int MESA_retain_pkt_update(const raw_pkt_t *p_raw_pkt, int pkt_ret)
+{
+ int update_ret = pkt_ret;
+
+ assert(p_raw_pkt->magic_num == RAW_PKT_MAGIC_NUM);
+ if(p_raw_pkt->magic_num != RAW_PKT_MAGIC_NUM )return pkt_ret;
+
+ if (p_raw_pkt->d_pkt != NULL)// have retain operation
+ {
+ if (p_raw_pkt->d_pkt->mark == RETAIN_RAWPKT) //retain pkt in use
+ {
+ if (pkt_ret == PASS)
+ {
+ update_ret = RETAIN;
+ }
+ if (pkt_ret == DROP)
+ {
+ p_raw_pkt->d_pkt->replica.io_lib_pkt_reference = NULL;
+ p_raw_pkt->d_pkt->replica.__lib_raw_pkt_data = NULL;
+ p_raw_pkt->d_pkt->replica.__lib_raw_pkt_len = 0;
+ }
+ p_raw_pkt->d_pkt->original = NULL;
+ }
+ else //During the processing of the original package, the retained pkt being called forward or free, so it is directly released
+ {
+ if (p_raw_pkt->d_pkt->mark == FREE_RAWPKT)
+ {
+ update_ret = DROP;
+ }
+ detain_pkt_mem_free(p_raw_pkt->d_pkt);
+ }
+ }
+ return update_ret;
+}
+
+int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value)
+{
+ int ret = 0;
+ const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt;
+
+ if(NULL == voidpkt || NULL == void_value){
+ return -1;
+ }
+
+ if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ��๦�� */
+ return -1;
+ }
+
+ switch(type){
+ case RAW_PKT_GET_DATA:
+ {
+ void **out_value = (void **)void_value;
+ *out_value = (char *)rawpkt->raw_pkt_data + rawpkt->overlay_layer_bytes;
+ }
+ break;
+
+ case RAW_PKT_GET_RAW_PKT_TYPE:
+ {
+ enum addr_type_t *out_value = (enum addr_type_t *)void_value;
+ *out_value = rawpkt->low_layer_type;
+ }
+ break;
+
+ case RAW_PKT_GET_TOT_LEN:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = rawpkt->raw_pkt_len - rawpkt->overlay_layer_bytes;
+ }
+ break;
+
+ case RAW_PKT_GET_TIMESTAMP:
+ {
+ struct timeval *out_value =(struct timeval *)void_value;
+ memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval));
+ }
+ break;
+
+ case RAW_PKT_GET_THIS_LAYER_HDR:
+ {
+ void **out_value = (void **)void_value;
+ const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr;
+ *out_value = (void *)this_layer_hdr;
+ }
+ break;
+
+ case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr;
+ }
+ break;
+
+ case RAW_PKT_GET_VIRTUAL_LINK_ID:
+ {
+ /* from sapp v4.2, there is no mrtunnat module, so not support this option! */
+ sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_VIRTUAL_LINK_ID' in sappv4.2 and later!");
+ ret = -1;
+ }
+ break;
+
+ case RAW_PKT_GET_REHASH_INDEX:
+ {
+ /* from sapp v4.2, there is no mrtunnat module, so not support this option! */
+ sapp_log(20, 0, 20, "not support option 'RAW_PKT_GET_REHASH_INDEX' in sappv4.2 and later!");
+ ret = -1;
+ }
+ break;
+
+
+ /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */
+ case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC:
+ {
+ const struct mesa_ethernet_hdr *lowest_ehdr;
+
+ if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat
+ if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
+ if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){
+ const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
+ if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */
+ ret = -1;
+ }else{
+ memcpy(void_value, mr_ctrlzone->g_device_mac, ETH_ALEN);
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!");
+ ret = -1;
+ }
+ }else{
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN);
+ }
+ }else{ //from v4.2, without mrtunnat
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_shost, ETH_ALEN);
+ }
+ }
+ break;
+
+ /* ���ڲ����ȡ��ײ���ʵmac��ַ, ����ʲôģʽ, ��û��mrtunnat, ������һ���ӿ� */
+ case RAW_PKT_GET_ORIGINAL_LOWEST_ETH_DMAC:
+ {
+ const struct mesa_ethernet_hdr *lowest_ehdr;
+
+ if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){ //with mrtunnat
+ if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
+ if(CAP_MODEL_MARSIOV4 == g_packet_io_cap_mode){
+ const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
+ if(0 == (mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)){/* ��vxlan��, �϶�û����Щѡ�� */
+ ret = -1;
+ }else{
+ memcpy(void_value, mr_ctrlzone->l_device_mac, ETH_ALEN);
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "can't support option 'RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC' in no marsio inline mode!");
+ ret = -1;
+ }
+ }else{
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN);
+ }
+ }else{ //from v4.2, without mrtunnat
+ lowest_ehdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, lowest_ehdr->ether_dhost, ETH_ALEN);
+ }
+ }
+ break;
+
+ default:
+ sapp_runtime_log(RLOG_LV_FATAL, "get_opt_from_rawpkt(): not support option type: %d", type);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+
+static const struct streaminfo_private *offset_to_vxlan_layer(const struct streaminfo_private *pstream_pr)
+{
+ while(pstream_pr && (ADDR_TYPE_VXLAN != pstream_pr->stream_public.addr.addrtype)){
+ pstream_pr = pstream_pr->pfather_pr;
+ }
+
+ return pstream_pr;
+}
+
+
+static int get_vxlan_info_from_streaminfo(const struct streaminfo_private *pstream_pr, int type, void *void_value)
+{
+ int ret = 0;
+ const struct streaminfo_private *vxlan_pstream_pr;
+ const raw_pkt_t *rawpkt;
+ const inline_vxlan_hdr_t *p_vxlan_hdr;
+
+ if(DEPOLYMENT_MODE_INLINE != g_topology_mode_raw){
+ sapp_runtime_log(RLOG_LV_INFO, "get_rawpkt_opt_from_streaminfo() error: can't support option type: %d in no inline mode!", type);
+ return -1;
+ }
+
+ vxlan_pstream_pr = offset_to_vxlan_layer(pstream_pr);
+ if(NULL == vxlan_pstream_pr){
+ sapp_runtime_log(RLOG_LV_FATAL, "get_rawpkt_opt_from_streaminfo() error, stream:%s not found vxlan layer!",
+ printaddr(&pstream_pr->stream_public.addr, pstream_pr->stream_public.threadnum));
+ return -1;
+ }
+
+ rawpkt = pstream_pr->raw_pkt;
+ p_vxlan_hdr = (inline_vxlan_hdr_t *)((char *)rawpkt->raw_pkt_data + vxlan_pstream_pr->offset_to_raw_pkt_hdr);
+
+ switch(type){
+ case RAW_PKT_GET_GDEV_IP:
+ {
+ const struct mesa_ip4_hdr *pip4_hdr;
+ const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
+ if(NULL == carry_vxlan_ip_layer){
+ return -1;
+ }
+
+ pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
+ int *out_value = (int *)void_value;
+ *out_value = pip4_hdr->ip_src.s_addr;
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_LOCAL_IP:
+ {
+ const struct mesa_ip4_hdr *pip4_hdr;
+ const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
+ if(NULL == carry_vxlan_ip_layer){
+ return -1;
+ }
+
+ pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
+ int *out_value = (int *)void_value;
+ *out_value = pip4_hdr->ip_dst.s_addr;
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_ID:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = htonl((int)p_vxlan_hdr->link_id);
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_VPNID:
+ {
+ int local_tmp_vpn_id;
+ local_tmp_vpn_id = ((int)p_vxlan_hdr->vlan_id_half_high << 4) | (int)p_vxlan_hdr->vlan_id_half_low;
+ int *out_value = (int *)void_value;
+ *out_value = htonl(local_tmp_vpn_id);
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_SPORT:
+ {
+ const struct mesa_ip4_hdr *pip4_hdr;
+ const struct mesa_udp_hdr *pudp_hdr;
+ const struct streaminfo_private *carry_vxlan_ip_layer = vxlan_pstream_pr->pfather_pr;
+ if(NULL == carry_vxlan_ip_layer){
+ return -1;
+ }
+
+ pip4_hdr = (struct mesa_ip4_hdr *)((char *)rawpkt->raw_pkt_data + carry_vxlan_ip_layer->offset_to_raw_pkt_hdr);
+ pudp_hdr = (struct mesa_udp_hdr *)((char *)pip4_hdr + pip4_hdr->ip_hl*4);
+ unsigned short *out_value = (unsigned short *)void_value;
+ *out_value = pudp_hdr->uh_sport; /* ���հ��ĽǶ�����, src port��inline�豸��sport */
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_ENCAP_TYPE:
+ {
+ char *out_value = (char *)void_value;
+ *out_value = p_vxlan_hdr->link_layer_type;
+ }
+ break;
+
+ case RAW_PKT_GET_VXLAN_LINK_DIR:
+ {
+ char *out_value = (char *)void_value;
+ *out_value = p_vxlan_hdr->dir;
+ }
+ break;
+
+ /* ���հ��ĽǶ�����, src host��inline�豸��mac */
+ case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC:
+ {
+ const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, p_eth_hdr->ether_shost, ETH_ALEN);
+ }
+ break;
+
+ /* ���հ��ĽǶ�����, dst host�DZ�����mac */
+ case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC:
+ {
+ const struct mesa_ethernet_hdr *p_eth_hdr = (struct mesa_ethernet_hdr *)rawpkt->raw_pkt_data;
+ memcpy(void_value, p_eth_hdr->ether_dhost, ETH_ALEN);
+ }
+ break;
+ }
+
+ return ret;
+}
+
+const void *get_rawpkt_from_streaminfo(const struct streaminfo *pstream)
+{
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ if(pstream_pr->packet_io_context != 0)
+ {
+ return pstream_pr->raw_pkt;
+ }
+ return NULL;
+}
+
+int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value)
+{
+ int ret = -1;
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+
+ if(NULL == out_value){
+ return -1;
+ }
+
+ if((RAW_PKT_GET_DATA == type)
+ && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){
+ const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream);
+ if(NULL == list_tmp){
+ ret = -1;
+ }else{
+ const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value;
+ *out_list = list_tmp;
+ ret = 1;
+ }
+ return ret;
+ }
+
+ /* sappv4.2֮��, û��mrtunnat, �޷���ctrlzone��ȡ��Щvxlan��ص�ֵ, Ҫ��streaminfo->pfatherƫ�ƻ�ȡ */
+ switch(type){
+ case RAW_PKT_GET_GDEV_IP:
+ case RAW_PKT_GET_VXLAN_ID:
+ case RAW_PKT_GET_VXLAN_SPORT:
+ case RAW_PKT_GET_VXLAN_ENCAP_TYPE:
+ case RAW_PKT_GET_VXLAN_LINK_DIR:
+ case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC:
+ case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC:
+ case RAW_PKT_GET_VXLAN_VPNID:
+ case RAW_PKT_GET_VXLAN_LOCAL_IP:
+ return get_vxlan_info_from_streaminfo(pstream_pr, type, out_value);
+ break;
+ }
+
+ return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value);
+}
+
+/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/
+const char *printaddr (const struct layer_addr *paddrinfo,int threadindex)
+{
+ static char maxbuf[MAX_THREAD_NUM][128];
+ char *buf=(char*)maxbuf[threadindex];
+ char ip_str[INET6_ADDRSTRLEN];
+ struct stream_tuple4_v4 *paddr;
+ struct stream_tuple4_v6 *paddr6;
+
+ if(NULL == paddrinfo){
+ return NULL;
+ }
+
+ switch(paddrinfo->addrtype){
+ case ADDR_TYPE_IPV4:
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,64);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
+ //strcat (buf, int_ntoa (paddr->daddr));
+ inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
+ }
+ break;
+
+ case ADDR_TYPE_IPV6:
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
+ inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V4:
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,128);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ strcat (buf, ">");
+ inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ strcat (buf, ">");
+ inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ }
+ break;
+
+ default:
+ {
+ return (const char *)"Not support layer type";
+ }
+ break;
+ }
+
+ return buf;
+}
+
+/*
+ This is a reentrant version of printaddr(),
+ Convert tuple4 to string store in out_buf.
+ Format: 10.0.0.1, 1234->10.0.0.2,5678.
+*/
+const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len)
+{
+ char maxbuf[128];
+ char *buf=maxbuf;
+ char ip_str[INET6_ADDRSTRLEN];
+ int addr_str_len;
+ struct stream_tuple4_v4 *paddr;
+ struct stream_tuple4_v6 *paddr6;
+
+ if((NULL == paddrinfo) || (NULL == out_buf)){
+ return "invalid args";
+ }
+
+ if(paddrinfo->addrtype==ADDR_TYPE_IPV4)
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,128);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strncpy (buf, ip_str, 64);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
+ //strcat (buf, int_ntoa (paddr->daddr));
+ inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
+ }
+ //to addjust
+ else if(paddrinfo->addrtype==ADDR_TYPE_IPV6)
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strncpy (buf, ip_str,64);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
+ inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
+ }
+ else
+ {
+ return (const char *)"Not support layer type";
+ }
+
+ addr_str_len = strlen(buf) + 1; /* add EOF */
+ if(addr_str_len > out_buf_len){
+ return (const char *)"buf len not enough";
+ }
+
+ memcpy(out_buf, buf, addr_str_len);
+
+ return out_buf;
+}
+
+
+struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info)
+{
+ void *addr_value;
+ struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr));
+ addr_value = malloc(stack_info->addrlen);
+
+ memcpy(heap_addr, stack_info, sizeof(struct layer_addr));
+ memcpy(addr_value, stack_info->paddr, stack_info->addrlen);
+ heap_addr->paddr = addr_value;
+
+ return heap_addr;
+}
+
+void layer_addr_free(struct layer_addr *paddrinfo)
+{
+ free(paddrinfo->paddr);
+ free(paddrinfo);
+}
+
+int get_thread_count(void)
+{
+ return g_packet_io_thread_num;
+}
+
+/*
+ ctype:
+ 'c':count;
+ 'l':length;
+*/
+static inline unsigned long long __get_stream_opt_traffic_raw(int cltype, int iotype, struct streaminfo_private *pstream_pr)
+{
+ unsigned long long tval;
+ struct streaminfo *pstream = &pstream_pr->stream_public;
+
+ if('c' == cltype){ /* count */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }
+ }
+ }else{/* length */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->S2C_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->S2C_all_byte_raw;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = ((struct tcpdetail_private *)pstream->ptcpdetail)->flow_stat->C2S_all_byte_raw;
+ }else{
+ tval = ((struct udpdetail_private *)pstream->pudpdetail)->flow_stat->C2S_all_byte_raw;
+ }
+ }
+ }
+ }
+
+ return tval;
+}
+
+
+
+/*
+ ctype:
+ 'c':count;
+ 'l':length;
+*/
+static inline unsigned long long __get_stream_opt_traffic(int cltype, int iotype, struct streaminfo_private *pstream_pr)
+{
+ unsigned long long tval;
+ struct streaminfo *pstream = &pstream_pr->stream_public;
+
+ if('c' == cltype){ /* count */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientpktnum;
+ }else{
+ tval = pstream->pudpdetail->clientpktnum;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverpktnum;
+ }else{
+ tval = pstream->pudpdetail->serverpktnum;
+ }
+ }
+ }
+ }else{/* length */
+ if('i' == iotype){ /* inbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverbytes;
+ }else{
+ tval = pstream->pudpdetail->serverbytes;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientbytes;
+ }else{
+ tval = pstream->pudpdetail->clientbytes;
+ }
+ }
+ }else{ /* outbound */
+ if(sapp_global_val->config.packet_io.inbound_route_dir == pstream_pr->stream_c2s_route_dir){
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->clientbytes;
+ }else{
+ tval = pstream->pudpdetail->clientbytes;
+ }
+ }else{
+ if(STREAM_TYPE_TCP == pstream_pr->stream_public.type){
+ tval = pstream->ptcpdetail->serverbytes;
+ }else{
+ tval = pstream->pudpdetail->serverbytes;
+ }
+ }
+ }
+ }
+
+ return tval;
+}
+
+
+int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len)
+{
+ int ret = -1;
+
+ if((NULL == opt_val) || (opt_val_len <= 0)){
+ return -1;
+ }
+
+ switch((int)opt){
+ case (int)MSO_MAX_UNORDER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ if(opt_val_len != sizeof(struct max_unorder_opt)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val;
+ ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val);
+ }
+ break;
+
+ case (int)MSO_NEED_ACK:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char nack = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->needackflag = nack;
+ ret = 0;
+ }
+ break;
+
+ case (int)MSO_TAKEOVER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() STREAM_TYPE_TCP error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ int takeover = *((int *)opt_val);
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->takeoverflag = takeover;
+ ret = 0;
+ }
+ break;
+
+ case (int)MSO_TIMEOUT:
+ {
+ if(sizeof(short) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned short tmout = *((unsigned short *)opt_val);
+ ret = stream_set_single_stream_timeout(pstream, tmout);
+ }
+ break;
+
+ case (int)MSO_IGNORE_RST_FIN:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_IGNORE_RST_FIN error: stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char igrstfin = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->ignore_rst_fin = igrstfin;
+ ret = 0;
+ }
+ break;
+
+ case MSO_TCPALL_VALID_AFTER_KILL:
+ {
+#if 0
+ if(STREAM_TYPE_TCP != pstream->type){
+ printf("MESA_set_stream_opt() error: stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ unsigned char tcpall_valid = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->tcpall_valid_after_kill = (tcpall_valid == 1 ? 1 : 0);
+ ret = 0;
+#else
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCPALL_VALID_AFTER_KILL error: this option is obsoleted!\n", printaddr(&pstream->addr, pstream->threadnum));
+#endif
+ }
+ break;
+
+ case MSO_DROP_STREAM:
+ {
+ int drop_flag = *((int *)opt_val);
+ if(STREAM_TYPE_TCP == pstream->type){
+ struct tcpdetail_private *tcp_pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ tcp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0);
+ ret = 0;
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ struct udpdetail_private *udp_pdetail_pr=(struct udpdetail_private*)(pstream->pdetail);
+ udp_pdetail_pr->drop_stream_flag = (drop_flag != 0 ? 1:0);
+ ret = 0;
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_set_stream_opt() MSO_DROP_STREAM error: stream type is not tcp or udp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_TCP_RST_REMEDY:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_TCP_RST_REMEDY error: stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ int remedy_flag = *((int *)opt_val);
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->auto_remedy_flag = (remedy_flag != 0 ? 1:0);
+ ret = 0;
+ }
+ break;
+
+ case MSO_DROP_CURRENT_PKT:
+ {
+ struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream;
+ raw_pkt_t *raw_pkt = (raw_pkt_t *)pstream_pr->raw_pkt;
+ int drop_value = *((int *)opt_val);
+ if(raw_pkt){
+ raw_pkt->drop_current_pkt_flag = drop_value;
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_set_stream_opt() MSO_DROP_CURRENT_PKT error: current pkt is NULL!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ }
+ }
+ break;
+ case MSO_STREAM_TIMED:
+ {
+ if(sizeof(int) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned int set_timer_s = *((unsigned short *)opt_val);
+ struct stream_list *lru_list_root;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ StreamFunInfo *funinfo = (StreamFunInfo *)pstream_pr->cur_plugin_cb_func;
+ funinfo->pstream = pstream;
+ funinfo->set_timer_s = set_timer_s;
+ if(false == timeout_pending(&funinfo->timeout))
+ {
+ timeout_init(&funinfo->timeout, TIMEOUT_ABS);
+ G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer_cnt+=1;
+ }
+ timeouts_add(G_MESA_GLOBAL_STREAM[pstream->threadnum]->user_define_timer, &funinfo->timeout, set_timer_s+g_CurrentTime);
+ ret = 0;
+ }
+ break;
+ case MSO_STREAM_APPLEND_SEGMENT_ID_LIST:
+ {
+ if(sizeof(struct segment_id_list) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ if(pstream_pr->sid_append_list == NULL)
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ pstream_pr->sid_append_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list));
+ memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ }
+ else
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ memcpy(pstream_pr->sid_append_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_append_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ else
+ {
+ memset(pstream_pr->sid_append_list, 0, sizeof(struct segment_id_list));
+ }
+ }
+ ret = 0;
+ }
+ break;
+ case MSO_STREAM_PREPLEND_SEGMENT_ID_LIST:
+ {
+ if(sizeof(struct segment_id_list) != opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() MSO_STREAM_APPLEND_SEGMENT_ID_LIST error:opt_val_len invalid, must be sizeof(struct segment_id_list)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ struct segment_id_list *set_sid_list = (struct segment_id_list *)opt_val;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ if(pstream_pr->sid_prepend_list == NULL)
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ pstream_pr->sid_prepend_list = (struct segment_id_list *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, pstream->threadnum, sizeof(struct segment_id_list));
+ memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ }
+ else
+ {
+ if(set_sid_list->sz_sidlist > 0)
+ {
+ memcpy(pstream_pr->sid_prepend_list->sid_list, set_sid_list->sid_list, set_sid_list->sz_sidlist*sizeof(unsigned short));
+ pstream_pr->sid_prepend_list->sz_sidlist = set_sid_list->sz_sidlist;
+ }
+ else
+ {
+ memset(pstream_pr->sid_prepend_list, 0, sizeof(struct segment_id_list));
+ }
+ }
+ ret = 0;
+ }
+ break;
+ case MSO_STREAM_SET_DATAMETA_TRACE_ID:
+ {
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ if(pstream_pr->stream_trace_id>0)
+ {
+ break;
+ }
+ pstream_pr->stream_trace_id=*((unsigned long long *)opt_val);
+ }
+ break;
+ default:
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_set_stream_opt() error: unsupport MESA_stream_opt type:%d!\n", printaddr(&pstream->addr, pstream->threadnum), (int)opt);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
+{
+ struct max_unorder_opt out_val;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
+ UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0;
+
+ memset(&out_val, 0, sizeof(struct max_unorder_opt));
+ if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){
+ out_uorder_C2S = pdetail_pr->pserver->maxunorder;
+ out_val.stream_dir |= DIR_C2S;
+ }
+
+ if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){
+ out_uorder_S2C = pdetail_pr->pclient->maxunorder;
+ out_val.stream_dir |= DIR_S2C;
+ }
+
+ out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C;
+
+ memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt));
+
+ *opt_val_len = sizeof(struct max_unorder_opt);
+
+ return 0;
+}
+
+
+static void sapp_mac_addr_to_long(const unsigned char *mac_addr, unsigned long long *smac_integer_type)
+{
+ int i;
+ char *ptr = (char *)smac_integer_type;
+
+ ptr += 5; /* ָ��long long �ĵ�6���ֽ� */
+
+ for(i = 0; i < 6; i++){
+ *ptr-- = *mac_addr++; /* �������ݰ���mac�����λ, copy��long long���������λ(��ȥ���2���ֽں�) */
+ }
+}
+
+static int sapp_get_vxlan_info_from_streaminfo(const struct streaminfo *pstream, struct vxlan_info *vxinfo)
+{
+#define GDEV_SMAC_MASK_ENCAP_TYPE (0x00000000000F0000)
+#define GDEV_SMAC_MASK_ENTRANCE_ID (0x0000000000007C00)
+#define GDEV_SMAC_MASK_DEV_ID (0x00000000000003F0)
+#define GDEV_SMAC_MASK_LINK_ID (0x000000000000000E)
+#define GDEV_SMAC_MASK_LINK_DIR (0x0000000000000001)
+
+ int i;
+ const struct streaminfo *mim_stream = pstream->pfather;
+ const struct layer_addr_mac_in_mac *mim_addr;
+ const struct layer_addr_mac *mac_addr;
+ unsigned char *ptr;
+ unsigned long long smac_integer_type; /* 48bit macת��Ϊ64bit�ij��������ִ洢, ���ڲ��� */
+
+ while(mim_stream){//���ڶ��mac��ַ�������ֻ�������MAC��ַȡvxlan_info
+ if((ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype || ADDR_TYPE_MAC == mim_stream->addr.addrtype) &&
+ (mim_stream->pfather == NULL)){
+ break;
+ }else{
+ mim_stream = mim_stream->pfather;
+ }
+ }
+
+ if(NULL == mim_stream){
+ return -1;
+ }
+
+ memset(vxinfo, 0, sizeof(struct vxlan_info));
+
+ if (ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
+ {
+ mim_addr = mim_stream->addr.mimac;
+ sapp_mac_addr_to_long(mim_addr->outer_src_mac, &smac_integer_type);
+ }
+ else
+ {
+ mac_addr = mim_stream->addr.mac;
+ sapp_mac_addr_to_long(mac_addr->src_addr.h_source, &smac_integer_type);
+ }
+ vxinfo->encap_type = (smac_integer_type & GDEV_SMAC_MASK_ENCAP_TYPE) >> 16;
+ vxinfo->entrance_id = (smac_integer_type & GDEV_SMAC_MASK_ENTRANCE_ID) >> 10;
+ vxinfo->dev_id = (smac_integer_type & GDEV_SMAC_MASK_DEV_ID) >> 4;
+ vxinfo->link_id = (smac_integer_type & GDEV_SMAC_MASK_LINK_ID ) >> 1;
+ vxinfo->link_dir = (smac_integer_type & GDEV_SMAC_MASK_LINK_DIR);
+
+ if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
+ {
+ ptr = vxinfo->inner_smac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mim_addr->inner_src_mac[i]);
+ }
+ vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_smac_hex, mim_addr->inner_src_mac, 6);
+
+ ptr = vxinfo->inner_dmac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mim_addr->inner_dst_mac[i]);
+ }
+ vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_dmac_hex, mim_addr->inner_dst_mac, 6);
+ }
+ else
+ {
+ ptr = vxinfo->inner_smac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_source[i]);
+ }
+ vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_smac_hex, mac_addr->src_addr.h_source, 6);
+
+ ptr = vxinfo->inner_dmac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mac_addr->src_addr.h_dest[i]);
+ }
+ vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_dmac_hex, mac_addr->src_addr.h_dest, 6);
+ }
+ return 0;
+}
+
+
+static void *MESA_get_stream_plug_pme_from_platform_entry(const StreamFunInfo *plug_pme_head, const void *this_plug_entry)
+{
+ void *this_plug_pme = NULL;
+
+ while(plug_pme_head){
+ if(plug_pme_head->pfun == this_plug_entry){
+ this_plug_pme = plug_pme_head->pAppInfo;
+ break;
+ }
+ plug_pme_head = plug_pme_head->next;
+ }
+
+ return this_plug_pme;
+}
+
+/*
+ ���ݲ����ں���������, ��ȡ�����˽�д洢�ռ�ָ��pme.
+*/
+static int MESA_get_stream_plug_pme(const struct streaminfo *pstream, void *opt_val, const int *opt_val_len)
+{
+ int ret = 0;
+ struct mso_plug_pme *in_arg;
+ const struct streaminfo_private *stream_pr;
+ struct tcpdetail_private *ptcp_detail_pr;
+ struct udpdetail_private *pudp_detail_pr;
+
+ const void *this_plug_entry;
+ void *plug_pme;
+
+ if((NULL == opt_val) || (NULL == opt_val_len)){
+ return -1;
+ }
+
+ if(*opt_val_len != sizeof(struct mso_plug_pme)){
+ return -1;
+ }
+
+ in_arg = (struct mso_plug_pme *)opt_val;
+ stream_pr = (struct streaminfo_private *)pstream;
+ in_arg->plug_pme = NULL;
+
+ this_plug_entry = plugin_get_plug_entry(in_arg->plug_name, in_arg->plug_entry_type);
+ if(NULL == this_plug_entry){
+ sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, can't get plug:%s entry:%s address",
+ printaddr(&pstream->addr, pstream->threadnum), in_arg->plug_name, in_arg->plug_entry_type);
+ return -1;
+ }
+
+ if(STREAM_TYPE_TCP == pstream->type){
+ ptcp_detail_pr=(struct tcpdetail_private *)(pstream->pdetail);
+ plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->apme, this_plug_entry);
+ if(plug_pme != NULL){
+ in_arg->plug_pme = plug_pme;
+ goto bingo;
+ }
+ plug_pme = MESA_get_stream_plug_pme_from_platform_entry(ptcp_detail_pr->pAllpktpme, this_plug_entry);
+ if(plug_pme != NULL){
+ in_arg->plug_pme = plug_pme;
+ goto bingo;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ pudp_detail_pr = (struct udpdetail_private *)(pstream->pdetail);
+ plug_pme = MESA_get_stream_plug_pme_from_platform_entry(pudp_detail_pr->apme, this_plug_entry);
+ if(plug_pme != NULL){
+ in_arg->plug_pme = plug_pme;
+ goto bingo;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_FATAL, "%s, MESA_get_stream_opt() MSO_STREAM_PLUG_PME error, not support stream type:%d", printaddr(&pstream->addr, pstream->threadnum),pstream->type);
+ return -1;
+ }
+
+ if(NULL == in_arg->plug_pme){
+ ret = -1;
+ }
+
+bingo:
+
+ return ret;
+}
+
+
+static int MESA_get_stream_dup_pkt_stat(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
+{
+ const struct streaminfo_private *pstream_pr = (struct streaminfo_private *)pstream;
+ int *res_val = (int *)opt_val;
+ int ret = 0;
+
+ if((0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_all_inject)
+ && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_tcp)
+ && (0 == sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_udp)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, config DUPLICATE_PKT is not enable",
+ printaddr(&pstream->addr, pstream->threadnum));
+ *res_val = -2;
+ return 0;
+ }
+
+ if(pstream_pr->has_duplicate_pkt != 0){
+ *res_val = 1;
+ return 0;
+ }
+
+ /* �������ظ�����⹦��,����û�������ظ��� */
+ if(STREAM_TYPE_TCP == pstream->type){
+ if(pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */
+ *res_val = -2;
+ sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt",
+ printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum);
+ }else{
+ *res_val = 0;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ if(pstream->pudpdetail->clientpktnum + pstream->pudpdetail->serverpktnum < SAPP_DUP_FIRST_PKT_NUM){ /* ��̫��, �������ж���û���ظ��� */
+ sapp_runtime_log(RLOG_LV_DEBUG, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT, duplicate pkt state is pending, because has only recv %d pkt",
+ printaddr(&pstream->addr, pstream->threadnum), pstream->ptcpdetail->clientpktnum + pstream->ptcpdetail->serverpktnum);
+ *res_val = -2;
+ }else{
+ *res_val = 0;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_HAVE_DUP_PKT error, not support stream type:%d",
+ printaddr(&pstream->addr, pstream->threadnum), pstream->type);
+ *res_val = -2;
+ ret = -1;
+ }
+
+ return ret;
+}
+
+int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len)
+{
+ int ret = 0;
+
+ if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){
+ return -1;
+ }
+
+ switch((int)opt){
+ case (int)MSO_MAX_UNORDER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_MAX_UNORDER error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ *opt_val_len = sizeof(struct max_unorder_opt);
+ ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len);
+ }
+ break;
+
+ case (int)MSO_NEED_ACK:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_NEED_ACK error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char *nack = (unsigned char *)opt_val;
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *nack = pdetail_pr->needackflag;
+ *opt_val_len = sizeof(char);
+ }
+ break;
+
+ case (int)MSO_TAKEOVER:
+ {
+ if(*opt_val_len < (int)sizeof(int)){
+ ret = -1;
+ break;
+ }
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TAKEOVER error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ int *takeover = (int *)opt_val;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ *takeover = pdetail_pr->takeoverflag;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case (int)MSO_TIMEOUT:
+ {
+ if(sizeof(short) != *opt_val_len){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TIMEOUT error:opt_val_len invalid, must be sizeof(short)\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned short *tmout = (unsigned short *)opt_val;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ *tmout = pstream_pr->timeout;
+ *opt_val_len = sizeof(short);
+ }
+ break;
+
+ case (int)MSO_IGNORE_RST_FIN:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_IGNORE_RST_FIN error:stream type is not tcp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned char *igrstfin = (unsigned char *)opt_val;
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *igrstfin = pdetail_pr->ignore_rst_fin;
+ }
+ break;
+
+ case MSO_TCP_CREATE_LINK_MODE:
+ {
+ struct tcpdetail_private *pdetail_pr;
+ UCHAR *out_val = (UCHAR *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO,"%s, MESA_get_stream_opt() MSO_TCP_CREATE_LINK_MODE error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *out_val = pdetail_pr->creat_mod;
+ *opt_val_len = sizeof(char);
+ }
+ break;
+
+ case MSO_TCP_ISN_C2S:
+ {
+ struct tcpdetail_private *pdetail_pr;
+ UINT32 *out_val = (UINT32 *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: stream create mode is not by SYN!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ if(0 == pdetail_pr->iserverseq){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s, MESA_get_stream_opt() MSO_TCP_ISN_C2S error: can't get SYN seq!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ *out_val = pdetail_pr->iserverseq - 1;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case MSO_TCP_ISN_S2C:
+ {
+ /* TODO 1: �����������ظ�, ���ϲ� */
+ struct tcpdetail_private *pdetail_pr;
+ UINT32 *out_val = (UINT32 *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: stream create mode is not by SYN!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+
+ if(0 == pdetail_pr->iclientseq){
+ ret = -1;
+ if(pstream->dir != DIR_C2S)
+ {
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_ISN_S2C error: can't get SYN/ACK seq!\n",printaddr(&pstream->addr, pstream->threadnum));
+ }
+ break;
+ }
+
+ *out_val = pdetail_pr->iclientseq - 1;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case MSO_TCP_SYN_OPT:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ struct tcp_option **out_val = (struct tcp_option **)opt_val;
+ if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){
+ *out_val = pstream_pr->syn_opt_array;
+ *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
+ ret = 0;
+ }else{
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_TCP_SYNACK_OPT:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ struct tcp_option **out_val = (struct tcp_option **)opt_val;
+ if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){
+ *out_val = pstream_pr->synack_opt_array;
+ *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
+ ret = 0;
+ }else{
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_STREAM_TUNNEL_TYPE:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ unsigned short *out_val = (unsigned short *)opt_val;
+ *out_val = pstream_pr->stream_low_layer_tunnel_type;
+ ret = 0;
+ }
+ break;
+
+ case MSO_STREAM_UP_LAYER_TUNNEL_TYPE:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ unsigned short *out_val = (unsigned short *)opt_val;
+ *out_val = pstream_pr->stream_carry_up_layer_tunnel_type;
+ ret = 0;
+ }
+ break;
+
+ case MSO_STREAM_CLOSE_REASON:
+ {
+ UCHAR *close_reason = (UCHAR *)opt_val;
+
+ if(pstream->opstate != OP_STATE_CLOSE){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:has not closed!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ if(STREAM_TYPE_TCP == pstream->type){
+ const struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *close_reason = pdetail_pr->link_state;
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ *close_reason = pstream_pr->stream_close_reason;
+ }else{
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error:unsupport stream type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), pstream->type);
+ }
+ }
+ break;
+
+ case MSO_STREAM_VXLAN_INFO:
+ if(DEPOLYMENT_MODE_MIRROR != g_topology_mode_raw){
+ sapp_runtime_log(RLOG_LV_INFO, "MESA_get_stream_opt() error: can't support option MSO_STREAM_VXLAN_INFO in no mirror mode!");
+ return -1;
+ }
+ if(*opt_val_len != sizeof(struct vxlan_info)){
+ return -1;
+ }
+ ret = sapp_get_vxlan_info_from_streaminfo(pstream, (struct vxlan_info *)opt_val);
+ break;
+
+ case MSO_GLOBAL_STREAM_ID:
+ {
+ const struct streaminfo_private *pstream_pr;
+ if(*opt_val_len != sizeof(long long)){
+ return -1;
+ }
+ pstream_pr = (const struct streaminfo_private *)pstream;
+ unsigned long long *out_args = (unsigned long long *)opt_val;
+ unsigned long long dev_id = *out_args;
+ if(dev_id > 4095){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_GLOBAL_STREAM_ID error:invalid dev_id:%llu!\n", printaddr(&pstream->addr, pstream->threadnum), dev_id);
+ return -1;
+ }
+ unsigned long long local_global_id = pstream_pr->global_stream_id;
+
+ *out_args = local_global_id | (dev_id << 51);
+ ret = 0;
+ }
+ break;
+
+ case MSO_TOTAL_INBOUND_PKT:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *inbound_pkt = (unsigned long long *)opt_val;
+ *inbound_pkt = __get_stream_opt_traffic('c', 'i', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_OUTBOUND_PKT:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_PKT error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *outbound_pkt = (unsigned long long *)opt_val;
+ *outbound_pkt = __get_stream_opt_traffic('c', 'o', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_INBOUND_BYTE:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *inbound_byte = (unsigned long long *)opt_val;
+ *inbound_byte = __get_stream_opt_traffic('l', 'i', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_INBOUND_BYTE_RAW:
+ {
+ if(STREAM_TYPE_TCP == pstream->type){
+ if(G_TCP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ if(G_UDP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+
+ unsigned long long *inbound_byte = (unsigned long long *)opt_val;
+ *inbound_byte = __get_stream_opt_traffic_raw('l', 'i', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+
+ case MSO_TOTAL_OUTBOUND_BYTE:
+ {
+ if((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type)){
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_OUTBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *outbound_byte = (unsigned long long *)opt_val;
+ *outbound_byte = __get_stream_opt_traffic('l', 'o', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_TOTAL_OUTBOUND_BYTE_RAW:
+ {
+ if(STREAM_TYPE_TCP == pstream->type){
+ if(G_TCP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project tcp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else if(STREAM_TYPE_UDP == pstream->type){
+ if(G_UDP_FLOW_STAT_PROJECT_ID == -1){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE_RAW error: project udp_flow_stat is not enable!\n",printaddr(&pstream->addr, pstream->threadnum));
+ break;
+ }
+ }else{
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TOTAL_INBOUND_BYTE error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+
+ unsigned long long *outbound_byte = (unsigned long long *)opt_val;
+ *outbound_byte = __get_stream_opt_traffic_raw('l', 'o', (struct streaminfo_private *)pstream);
+ }
+ break;
+
+ case MSO_STREAM_CREATE_TIMESTAMP_MS:
+ {
+ if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type))
+ {
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_CREATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *timestamp_ms = (unsigned long long *)opt_val;
+ *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_create_timestamp_ms;
+ }
+ break;
+ case MSO_STREAM_LASTUPDATE_TIMESTAMP_MS:
+ {
+ if ((STREAM_TYPE_TCP != pstream->type) && (STREAM_TYPE_UDP != pstream->type))
+ {
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_STREAM_LASTUPDATE_TIMESTAMP_MS error: stream type is not tcp or udp!\n",printaddr(&pstream->addr, pstream->threadnum));
+ ret = -1;
+ break;
+ }
+ unsigned long long *timestamp_ms = (unsigned long long *)opt_val;
+ *timestamp_ms = ((struct streaminfo_private *)pstream)->stream_lastupdate_timestamp_ms;
+ }
+ break;
+
+ case MSO_STREAM_PLUG_PME:
+ ret = MESA_get_stream_plug_pme(pstream, opt_val, opt_val_len);
+ break;
+
+ case MSO_HAVE_DUP_PKT:
+ ret = MESA_get_stream_dup_pkt_stat(pstream, opt_val, opt_val_len);
+ break;
+
+ default:
+ sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n",printaddr(&pstream->addr, pstream->threadnum), (int)opt);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+int is_proxy_stream(const struct streaminfo *pstream)
+{
+ int ret = 0;
+
+ switch(pstream->type){
+ case STREAM_TYPE_SOCKS4:
+ case STREAM_TYPE_SOCKS5:
+ case STREAM_TYPE_HTTP_PROXY:
+ case STREAM_TYPE_OPENVPN:
+ ret = 1;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+
+void set_current_thread_cpu_affinity(int thread_index)
+{
+ if(sapp_global_val->config.cpu.bind_mask_array_num != 0){
+ cpu_set_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(sapp_global_val->config.cpu.bind_mask_array[thread_index], &cpuset);
+ pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
+ }
+
+ return;
+}
+
+int get_current_thread_cpu_affinity_id(void)
+{
+ int i;
+ cpu_set_t current_cpu_mask;
+
+ CPU_ZERO(&current_cpu_mask);
+
+ if(pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &current_cpu_mask) < 0){
+ return -1;
+ }
+
+ int tot_cpu_core = get_nprocs();
+ int tot_cpu_set_count = CPU_COUNT(&current_cpu_mask);
+ if((tot_cpu_set_count == tot_cpu_core) || (tot_cpu_set_count > 1)){
+ /* ȫ����������, ��ʵ����û�а�,
+ �����������isolcpus, ���㲻���, CPU_COUNT���ܺ������������,
+ ��������1���϶���û�о�ȷ�󶨵�ij������ */
+ return -1;
+ }
+
+ for(i = 0; i <= tot_cpu_core; i++){
+ if(CPU_ISSET(i, &current_cpu_mask)){
+ break;
+ }
+ }
+
+ return i;
+}
+
+
+
+extern int project_req_terminal_tag_id;
+/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */
+const unsigned char *get_terminal_tag(struct streaminfo *stream)
+{
+ unsigned char *terminal_tag;
+
+ if(project_req_terminal_tag_id < 0){
+ return NULL;
+ }
+
+ terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id);
+
+ return (const unsigned char *)terminal_tag;
+}
+
+int number_is_2powerN(uint n)
+{
+ if(n & (n-1)){
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+void *dictator_malloc(int thread_seq,size_t size)
+{
+ /*
+ if(malloccount%100000==0)
+ {
+ printf("malloc=%d,free=%d\n",malloccount,freecount);
+ }
+ */
+
+ if(G_DICTATOR_SW){
+#if USE_MEMPOOL
+ return __dictator_malloc(thread_seq, size);
+#endif
+ }
+
+ return malloc(size);
+}
+void dictator_free(int thread_seq,void *pbuf)
+{
+#if USE_MEMPOOL
+ if(G_DICTATOR_SW){
+ __dictator_free(thread_seq, pbuf);
+ }
+ else
+#endif
+ {
+#if SAPP_INSECTICIDE
+ *((char *)pbuf) = 0xFE;
+#endif
+ free(pbuf);
+ }
+}
+
+void *dictator_realloc(int thread_seq, void *ptr, size_t size)
+{
+#if USE_MEMPOOL
+ if(G_DICTATOR_SW){
+ return __dictator_realloc(thread_seq, ptr, size);
+ }
+#endif
+
+ return realloc(ptr, size);
+}
+
+/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */
+char biz_retval_to_platform(char biz_ret)
+{
+ char plat_ret = 0;
+
+ if(biz_ret & PROT_STATE_GIVEME){
+ plat_ret |= APP_STATE_GIVEME;
+ }
+
+ if(biz_ret & PROT_STATE_DROPME){
+ plat_ret |= APP_STATE_DROPME;
+ }
+
+ if(biz_ret & PROT_STATE_DROPPKT){
+ plat_ret |= APP_STATE_DROPPKT;
+ }
+
+ return plat_ret;
+}
+
+/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */
+char plat_state_to_biz(char plat_state)
+{
+ char biz_ret = SESSION_STATE_CLOSE;
+
+ switch(plat_state){
+ case OP_STATE_PENDING:
+ biz_ret = SESSION_STATE_PENDING;
+ break;
+
+ case OP_STATE_DATA:
+ biz_ret = SESSION_STATE_DATA;
+ break;
+
+ case OP_STATE_CLOSE:
+ biz_ret = SESSION_STATE_CLOSE;
+ break;
+
+ default:
+ break;
+ }
+
+ return biz_ret;
+}
+
+
+long long sapp_get_cpu_cycle(void)
+{
+#ifdef __x86_64
+#define X86_64_ENV 1
+#endif
+#ifdef __x86_64__
+#define X86_64_ENV 1
+#endif
+
+#ifdef X86_64_ENV
+ long long l;
+ long long h;
+
+ __asm__ volatile("rdtsc" : "=a"(l), "=d"(h));
+ return (long long )l | ((long long )h<<32);
+#else
+ return 0;
+#endif
+}
+
+void sapp_set_current_state(enum sapp_state_t state)
+{
+ sapp_global_val->individual_volatile->current_state = (int)state;
+}
+
+enum sapp_state_t sapp_get_current_state(void)
+{
+ return (enum sapp_state_t)sapp_global_val->individual_volatile->current_state;
+}
+
+int sapp_size_of_sapp_global(void)
+{
+ return sizeof(sapp_global_t);
+}
+
+
+int sapp_size_of_streaminfo_private(void)
+{
+ return sizeof(struct streaminfo_private);
+}
+
+int sapp_size_of_tcpdetail_private(void)
+{
+ return sizeof(struct tcpdetail_private);
+}
+
+int sapp_size_of_udpdetail_private(void)
+{
+ return sizeof(struct udpdetail_private);
+}
+
+int sapp_size_of_raw_pkt_t(void)
+{
+ return sizeof(raw_pkt_t);
+}
+
+
+char *sapp_strdup(const char *raw_s)
+{
+ int buflen = strlen(raw_s) + 1; //add EOF
+ char *new_s = (char *)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, buflen);
+ memcpy(new_s, raw_s, buflen);
+
+ return new_s;
+}
+
+int sapp_is_absolute_path(const char *filename)
+{
+ if('/' == filename[0]){
+ return 1;
+ }
+
+ return 0;
+}
+
+long long sapp_random(void)
+{
+ struct timespec curtime;
+
+ clock_gettime(CLOCK_MONOTONIC, &curtime);
+
+ return (curtime.tv_nsec * 131) ^ curtime.tv_sec;
+}
+
+int sapp_usleep(int usec)
+{
+ struct timespec sleep_time_val;
+
+ sleep_time_val.tv_sec = 0;
+ sleep_time_val.tv_nsec = usec * 1000;
+
+ nanosleep(&sleep_time_val, NULL);
+
+ return 0;
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/packet_io/packet_io_marsio.c b/src/packet_io/packet_io_marsio.c
index ca043c0..43504db 100644
--- a/src/packet_io/packet_io_marsio.c
+++ b/src/packet_io/packet_io_marsio.c
@@ -1,1339 +1,1406 @@
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "sapp_api.h"
-#include "sapp_private_api.h"
-#include "sapp_declaration.h"
-#include <assert.h>
-
-/*
- netconnection_mode:
- 1: ���������ղ���
- 2: һ�����鿨, ˫��˫��
- 3: һ��һ�鿨, ��������
-
-
- TODO 1:
- ��send_raw_pkt.conf���������ݴ洢��G_SND_RAW_PKT_INFO,
- ��ģ���䲻һ������Щ�����հ�, ���϶������Щ��������, ����ע�����ݰ�����Ӧ�õ���������,
- ��ȻҪ�ڳ�ʼ��ʱ����Щ�豸, ����send_path.
-*/
-typedef struct{
- int thread_seq;
- void *send_mbuf_mtod_ptr;
- marsio_buff_t *send_mbuf[1];
- struct mr_vdev *dev_up, *dev_down; /* GDEVģʽ��, ֱ��ʹ��dev_up[0]; ͬʱ����˫��������ģʽ */
- struct mr_sendpath *sendpath_up, *sendpath_down; /* ����ģʽ��, ֱ��ʹ��sendpath_up; ͬʱ����˫��������ģʽ */
-}marsio4_io_handle;
-
-
-
-
-#ifndef MAX_METADATA_LEN
-#define MAX_METADATA_LEN 16
-#endif
-
-struct rawpkt_metadata
-{
- char data[MAX_METADATA_LEN];
- unsigned int sz_data;
- struct segment_id_list raw_sid_list;
-};
-
-extern int marsio_buff_get_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
-extern int marsio_buff_set_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
-extern int marsio_buff_unset_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type);
-/*
- ������ͬʱ, ��tcpdump_mesaһ��, ���ڲ�������,
- ��ע�İ�����tcpdump_mesa����, ֱ���������ײ㲶�񼴿�.
-*/
-extern void cycle_pkt_dump_by_classify(int thread_seq, const raw_pkt_t *p_raw_pkt, enum _pkt_classify class_val);
-extern int G_PKT_DUMP_SW;
-
-
-int g_marsio4_version_VERSION_20190907;
-int g_marsio4_version_VERSION = 20190907;
-static PACKET_IO_CB_T g_marsio4_work_fun;
-static int g_marsio4_work_thread_num = 1;
-static int g_marsio4_cap_level = CAP_LEVEL_MAC;
-static int g_marsio4_topology_mode = NET_CONN_PARALLEL;
-static int marsio4_work_thread_seq[MAX_THREAD_NUM];
-static pthread_t marsio4_work_tid[MAX_THREAD_NUM];
-extern int g_use_MESA_sleep_sw;
-struct mr_instance * sapp_marsio4_instance = NULL; /* ��ʱ���⿪��,������Ϊstatic */
-static int g_mr4_device_num = 0;
-static char **g_mr4_up_device_name; /* �豸���Ƽ���, meth0, meth1, meth2... */
-static char **g_mr4_down_device_name; /* �豸���Ƽ���, meth0, meth1, meth2... */
-static struct mr_vdev **g_mr4_dev_up_handle_set, **g_mr4_dev_down_handle_set; /* �豸������� */
-static struct mr_sendpath **g_mr4_sendpath_up_set, **g_mr4_sendpath_down_set; /* ����·��(���)���� */
-static marsio4_io_handle *g_mario4_io_handle;
-static void *marsio_so_handle;
-
-#define MARSIO_BURST_PKT_MAX (256)
-static int marsio4_burst_process_pkt_num = 32; /* ������������, ��pag.conf�л�ȡ */
-//static long marsio4_thread_bind_mask = 0;
-#define TIME_DELAY_MONITOR (0) /* ����������ʱ��� */
-
-extern void timestamp_region_update_driver(int tid, long long cpu_cycle);
-extern int stream_process_polling(int thread_seq);
-
-/* dlopen funtion pointer */
-static int (*ptr_marsio_option_set)(struct mr_instance * instance, marsio_opt_type_t opt_type, void * opt, size_t sz_opt);
-static void (*ptr_marsio_send_burst_flush)(struct mr_sendpath * sendpath, queue_id_t sid);
-static int (*ptr_marsio_init)(struct mr_instance * instance, const char * appsym);
-static struct mr_vdev * (*ptr_marsio_open_device)(struct mr_instance * instance,
- const char * devsym, unsigned int nr_rxstream, unsigned int nr_txstream);
-static void (*ptr_marsio_close_device)(struct mr_vdev *vdev);
-static struct mr_sendpath * (*ptr_marsio_sendpath_create_by_vdev)(struct mr_vdev * dest_device);
-static void (*ptr_marsio_sendpath_destory)(struct mr_sendpath * sendpath);
-static struct mr_instance * (*ptr_marsio_create)(void);
-static int (*ptr_marsio_destory)(struct mr_instance *instance);
-static int (*ptr_marsio_thread_init)(struct mr_instance * instance);
-static int (*ptr_marsio_recv_burst)(struct mr_vdev * vdev, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs);
-int (*ptr_marsio_send_burst)(struct mr_sendpath * sendpath, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs);
-static int (*ptr_marsio_send_burst_with_options)(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[], int nr_mbufs, uint16_t options);
-void (*ptr_marsio_buff_free)(struct mr_instance * instance, marsio_buff_t *marsio_buff[],unsigned int nr_mbufs, int socket_id, int thread_id);
-int (*ptr_marsio_buff_malloc_global)(struct mr_instance * instance, marsio_buff_t *marsio_buff[], unsigned int nr_mbufs, int socket_id, int thread_id);
-char * (*ptr_marsio_buff_append)(marsio_buff_t *m, uint16_t len);
-void * (*ptr_marsio_buff_ctrlzone)(marsio_buff_t *m, uint8_t id);
-void (*ptr_marsio_buff_ctrlzone_set)(marsio_buff_t *m, uint8_t id, void* ptr_data, uint8_t size);
-void (*ptr_marsio_buff_set_rehash_index)(marsio_buff_t *m, uint32_t hash);
-char * (*ptr_marsio_buff_mtod)(marsio_buff_t *m);
-uint32_t (*ptr_marsio_buff_datalen)(marsio_buff_t *m);
-uint32_t (*ptr_marsio_buff_buflen)(marsio_buff_t *m);
-marsio_buff_t * (*ptr_marsio_buff_clone_with_options)(struct mr_instance * instance, marsio_buff_t * md, int socket_id, int thread_id, uint16_t options);
-int (*ptr_marsio_buff_get_metadata)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
-int (*ptr_marsio_buff_set_metadata)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
-int (*ptr_marsio_buff_unset_metadata)(marsio_buff_t *m, enum mr_buff_metadata_type type);
-marsio_buff_t *(*ptr_marsio_buff_malloc_smartoffload)(struct mr_vdev *vdev, const char * pkt, unsigned int pkt_len);
-
-int (*ptr_marsio_buff_get_sid_list)(marsio_buff_t * m, uint16_t * out_slist, uint8_t sz_out_slist);
-int (*ptr_marsio_buff_set_sid_list)(marsio_buff_t * m, uint16_t * slist, uint8_t sz_slist);
-int (*ptr_marsio_buff_append_sid_list)(marsio_buff_t * m, uint16_t * slist, uint8_t sz_slist);
-int (*ptr_marsio_buff_prepend_sid_list)(marsio_buff_t * m, uint16_t * slist, uint8_t sz_slist);
-
-
-static struct bpf_program MARSIO_BPF_FILTER[MAX_THREAD_NUM];
-static int g_marsio_have_bpf;
-
-struct __marsio_bpf_counter_t
-{
- long count;
-} __attribute__((aligned(64))); /* for multi-thread, must 64byte alignment */
-struct __marsio_bpf_counter_t g_marsio_bpf_counter[MAX_THREAD_NUM];
-
-/************************ funcitons for dynamic link *************************/
-
-int marsio_dl_io_set_cap_level(int cap_level)
-{
- g_marsio4_cap_level = cap_level;
-
- return 0;
-}
-
-int marsio_dl_io_set_cap_mode(int cap_mode)
-{
- (void)cap_mode;
- return 0;
-}
-
-int marsio_dl_io_set_topology_mode(int topology_mode)
-{
- switch(topology_mode){
- case NET_CONN_PARA_NOSEND:
- case NET_CONN_PARALLEL:
- case NET_CONN_SERIAL_GDEV:
- case NET_CONN_SERIAL_2CARD:
- g_marsio4_topology_mode = topology_mode;
- break;
-
-
- default:
- printf("\033[1;31;40m[Error]Invalid net_connection_mode!\033[0m\n");
- return -1;
- }
-
- return 0;
-}
-
-int marsio_dl_io_set_capdev_parallel(const char *cap_dev)
-{
- char *save_ptr, *tmp_cap_dev_name;
- const char *delim = ", ";
- char cfg_name_from_conf[1024];
- char *single_device;
-
- /* marsio4ģʽ�������������ж��, ����ԭ�е�pcapdevice����, �����ŷָ� */
- if(NULL == cap_dev){
- printf("\033[1;31;40m[Error]Invalid pcapdevice!\033[0m\n");
- return -1;
- }
-
- /* marsioģʽ֧�ֶ�����, ���ŷָ�ģʽ */
- strncpy(cfg_name_from_conf, sapp_global_val->config.packet_io.internal.interface.name, sizeof(cfg_name_from_conf));
- tmp_cap_dev_name = cfg_name_from_conf;
-
- while((single_device = strtok_r(tmp_cap_dev_name, delim, &save_ptr)) != NULL){
- if(NULL == g_mr4_up_device_name){
- g_mr4_up_device_name = (char **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, sizeof(void *) * (g_mr4_device_num + 1));
- }else{
- g_mr4_up_device_name = (char **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, g_mr4_up_device_name, sizeof(void *) * (g_mr4_device_num + 1));
- }
-
- g_mr4_up_device_name[g_mr4_device_num] = sapp_strdup(single_device);
-
- g_mr4_device_num++;
- tmp_cap_dev_name = NULL;
- }
-
- return 0;
-}
-
-int marsio_dl_io_set_capdev_serial(const char *up_dev, const char *down_dev)
-{
- char *save_ptr;
- const char *delim = ", ";
- char *tmp_cap_dev_name, *save_mem_ptr;
- char *single_device;
- int local_mr4_serial_device_num = 0;
-
- /* marsio4ģʽ�������������ж��, ����ԭ�е�pcapdevice����, �����ŷָ� */
- if(NULL == down_dev){
- printf("\033[1;31;40m[Error]Invalid pcapdevice!\033[0m\n");
- return -1;
- }
-
- tmp_cap_dev_name = sapp_strdup(down_dev);
- save_mem_ptr = tmp_cap_dev_name;
-
- while((single_device = strtok_r(tmp_cap_dev_name, delim, &save_ptr)) != NULL){
- if(NULL == g_mr4_down_device_name){
- g_mr4_down_device_name = (char **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,sizeof(void *) * (local_mr4_serial_device_num + 1));
- }else{
- g_mr4_down_device_name = (char **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,g_mr4_down_device_name, sizeof(void *) * (local_mr4_serial_device_num + 1));
- }
-
- g_mr4_down_device_name[local_mr4_serial_device_num] = sapp_strdup(single_device);
-
- local_mr4_serial_device_num++;
- tmp_cap_dev_name = NULL;
- }
-
- if(local_mr4_serial_device_num != g_mr4_device_num){
- printf("\033[1;31;40m[Error]capture device up and down number is not match!\033[0m\n");
- return -1;
- }
-
- SAPP_GLOBAL_FREE(save_mem_ptr);
-
- return 0;
-}
-
-int marsio_dl_io_set_capture_filter(const char *filter_rule)
-{
- memset(&g_marsio_bpf_counter, 0, sizeof(g_marsio_bpf_counter));
- g_marsio_have_bpf=0;
-
- if(strlen(filter_rule) == 0)return -1;
- int i,j;
-
- int pcap_link_type = DLT_EN10MB;
- for (i = 0; i < (unsigned int)g_packet_io_thread_num; i++)
- {
- if (pcap_compile_nopcap(65535, pcap_link_type, &MARSIO_BPF_FILTER[i], filter_rule, 100, 0) < 0)
- {
- printf("Compile pcap filter '%s' error\n", filter_rule);
- for(j = 0; j < (unsigned int )g_packet_io_thread_num; j++)
- {
- pcap_freecode(&MARSIO_BPF_FILTER[j]);
- }
- return -1;
- }
- }
- g_marsio_have_bpf=1;
- return 0;
-}
-
-int marsio_dl_io_set_cap_buf_queue(int queue_num_max)
-{
- (void)queue_num_max; /* �������� */
- return 0;
-}
-
-int marsio_dl_io_set_work_thread_num(int thread_num_max)
-{
- g_marsio4_work_thread_num = thread_num_max;
- return 0;
-}
-
-
-long marsio_dl_io_get_app_drop_num(int thread_num)
-{
- /* pagģʽ�鿴������ר�ù���, ����Ŀǰ���ṩ�˹��� */
- (void)thread_num;
- return 0;
-}
-
-long marsio_dl_io_get_lib_drop_num(void)
-{
- long total_drop = 0;
- int i;
- for(i = 0; i < g_marsio4_work_thread_num; i++)
- {
- total_drop +=g_marsio_bpf_counter[i].count;
- }
- return total_drop;
-}
-
-
-unsigned char *marsio_dl_io_get_sendbuf(void *phandle, int thread_seq)
-{
-
- marsio4_io_handle *mr4_handle = (marsio4_io_handle *)phandle;
- mr4_handle->send_mbuf_mtod_ptr = malloc(SENDPACKET_PACKET_SIZE);
- return (unsigned char *)mr4_handle->send_mbuf_mtod_ptr;
-}
-
-void marsio_dl_io_free_sendbuf(void *phandle, int thread_seq)
-{
- marsio4_io_handle *mr4_handle = (marsio4_io_handle *)phandle;
- free(mr4_handle->send_mbuf_mtod_ptr);
- return;
-}
-
-/* 2020-10-30 lijia add, in/forward/inject����tcpdump_mesa, ����debug. */
-static void marsio_pkt_dump(int thread_seq, const marsio_buff_t *send_mbuf, enum _pkt_classify class)
-{
- raw_pkt_t to_tcpdump_mesa;
-
- if(0 == G_PKT_DUMP_SW){
- return;
- }
-
- to_tcpdump_mesa.low_layer_type = ADDR_TYPE_MAC;
- to_tcpdump_mesa.raw_pkt_data = ptr_marsio_buff_mtod((marsio_buff_t *)send_mbuf);
- to_tcpdump_mesa.raw_pkt_len = ptr_marsio_buff_buflen((marsio_buff_t *)send_mbuf);
- cycle_pkt_dump_by_classify(thread_seq, &to_tcpdump_mesa, class);
-
-}
-
-
-int marsio_dl_io_raw_pkt_send(void *phandle, unsigned char *data,int datalen, void *arg,
- int thread_seq, unsigned char route_dir, const raw_pkt_t *raw_pkt)
-{
- int ret;
- marsio_buff_t *send_mbuf[1];
- char *real_buf;
- struct mr_tunnat_ctrlzone mr_ctrlzone = {};
- uint16_t send_option = 0;
-
- ret = ptr_marsio_buff_malloc_global(sapp_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_seq);
- if((ret < 0) || (NULL == send_mbuf[0])){
- return -1;
- }
-
-
- /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
- real_buf = ptr_marsio_buff_append(send_mbuf[0], datalen);
- if(NULL == real_buf){
- ptr_marsio_buff_free(sapp_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_seq);
- return -1;
- }
-
- memcpy(real_buf, data, datalen);
-
- if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){
- mr_ctrlzone.action = TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- send_option = MARSIO_SEND_OPT_FAST|MARSIO_SEND_OPT_REHASH;
- }else{
- /* v4.2֮��, sapp����mrtunnat֧��, ֱ�ӷ���ԭʼ��, ����Ҫ������װ�ײ���·��Ϣ */
- mr_ctrlzone.action = TUNNAT_CZ_ACTION_ENCAP_NO_SESSION;
- send_option = MARSIO_SEND_OPT_FAST;
- }
-
- if(raw_pkt){
- packet_io_hook_sendto(raw_pkt, route_dir, real_buf, (void *)send_mbuf[0]);
- }
-
- ptr_marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
-
- ret = ptr_marsio_send_burst_with_options((struct mr_sendpath *)arg, thread_seq, send_mbuf, 1, send_option);
- if(ret < 0){
- return -1;
- }
- marsio_pkt_dump(thread_seq, send_mbuf[0], PKT_CLASSIFY_INJECT);
- return datalen;
-}
-
-int marsio_dl_io_low_level_send(void *phandle, UINT8 *data,int datalen,
- int eth_carry_layer_addr_type, int dir,int thread_num,const raw_pkt_t *raw_pkt)
-{
- int ret;
- struct mesa_ethernet_hdr *ehdr = (struct mesa_ethernet_hdr *)data;
- //��˫����͸��ģʽ(transparent)��, ����dirѡ��up or down device����.
- if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
- assert((dir >= 0) && (dir <= 1));
- ret = marsio_dl_io_raw_pkt_send(phandle, data, datalen, g_packet_device_alias[dir].dl_io_param, thread_num, dir, raw_pkt);
- }else{
- /* ��֧�ֶ������, ԭʼ�������յ��ʹ��ij�ȥ */
- ret = marsio_dl_io_raw_pkt_send(phandle, data, datalen, g_mr4_sendpath_up_set[raw_pkt->device_index], thread_num,dir, raw_pkt);
- }
-
- return ret;
-}
-
-int marsio_dl_io_smart_offload(int device_index, unsigned char *pkt_ptr, int pkt_len, unsigned char dir, int thread_num)
-{
- if(ptr_marsio_buff_malloc_smartoffload!=NULL && ptr_marsio_send_burst_with_options!=NULL)
- {
- /* for all vxlan pkts, create an offload request */
- marsio_buff_t * offload_request_buf = ptr_marsio_buff_malloc_smartoffload(g_mr4_dev_up_handle_set[device_index], (const char *)pkt_ptr, pkt_len);
- if(offload_request_buf==NULL)
- {
- return 0;
- }
- /* inject the offload request */
- ptr_marsio_send_burst_with_options(g_mr4_sendpath_up_set[device_index], thread_num, &offload_request_buf, 1, MARSIO_SEND_OPT_CTRL);
- return 1;
- }
- return 0;
-}
-
-static int marsio4_pkt_forward(int tid, struct mr_sendpath * sendpath, marsio_buff_t * mbufs);
-
-
-static void marsio_update_sid_list(const raw_pkt_t *raw_pkt, void *send_pkt_io_reference)
-{
- if(raw_pkt->append_list && ptr_marsio_buff_append_sid_list!= NULL)
- {
- ptr_marsio_buff_append_sid_list((marsio_buff_t *)send_pkt_io_reference, raw_pkt->append_list->sid_list, raw_pkt->append_list->sz_sidlist);
- }
- if(raw_pkt->prepend_list && ptr_marsio_buff_prepend_sid_list != NULL)
- {
- ptr_marsio_buff_prepend_sid_list((marsio_buff_t *)send_pkt_io_reference, raw_pkt->prepend_list->sid_list, raw_pkt->prepend_list->sz_sidlist);
- }
- return;
-}
-
-int marsio_dl_io_forward_rawpkt(const raw_pkt_t *raw_pkt, int thread_seq)
-{
- if(raw_pkt == NULL && (thread_seq < 0 || thread_seq > get_thread_count()))
- return -1;
- int ret = 0;
- if(raw_pkt->io_lib_pkt_reference != NULL)
- {
- marsio_update_sid_list(raw_pkt, (void *)raw_pkt->io_lib_pkt_reference);
- ret = marsio4_pkt_forward(thread_seq, g_mr4_sendpath_up_set[raw_pkt->device_index], (marsio_buff_t *)raw_pkt->io_lib_pkt_reference);
- }
- return ret;
-}
-
-void marsio_dl_io_free_rawpkt(const raw_pkt_t *raw_pkt, int thread_seq)
-{
- if(raw_pkt == NULL && (thread_seq < 0 || thread_seq > get_thread_count()))
- return;
- ptr_marsio_buff_free(sapp_marsio4_instance, (marsio_buff_t **)&raw_pkt->io_lib_pkt_reference, 1, MARSIO_SOCKET_ID_ANY, thread_seq);
- return;
-}
-
-
-struct rawpkt_metadata *marsio_dl_io_get1_rawpkt_meta(const raw_pkt_t *raw_pkt, int thread_seq)
-{
- struct rawpkt_metadata *meta = NULL;
- int ret = 0;
- if(raw_pkt->io_lib_pkt_reference != NULL)
- {
- if (ptr_marsio_buff_get_sid_list != NULL || ptr_marsio_buff_get_metadata != NULL)
- {
- meta = (struct rawpkt_metadata *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, thread_seq,sizeof(struct rawpkt_metadata));
- if (ptr_marsio_buff_get_metadata)
- {
- ret = ptr_marsio_buff_get_metadata((marsio_buff_t *)raw_pkt->io_lib_pkt_reference,
- MR_BUFF_ROUTE_CTX, meta->data, MAX_METADATA_LEN);
- if (ret <= 0)
- {
- sapp_mem_free(SAPP_MEM_DYN_SID_LIST, thread_seq,meta);
- return NULL;
- }
- else
- {
- meta->sz_data = ret;
- }
- }
- if (ptr_marsio_buff_get_sid_list)
- {
- ret = ptr_marsio_buff_get_sid_list((marsio_buff_t *)raw_pkt->io_lib_pkt_reference,
- meta->raw_sid_list.sid_list, MAX_SID_NUM);
- if (ret <= 0)
- {
- meta->raw_sid_list.sz_sidlist = 0;
- }
- else
- {
- meta->raw_sid_list.sz_sidlist = ret;
- }
- }
- if (meta->sz_data == 0 && meta->raw_sid_list.sz_sidlist == 0)
- {
- sapp_mem_free(SAPP_MEM_DYN_SID_LIST, thread_seq,meta);
- meta = NULL;
- }
- }
- }
-
- return meta;
-}
-
-
-
-void marsio_dl_io_set_rawpkt_meta(const raw_pkt_t *raw_pkt, void *send_pkt_io_reference, unsigned char route_dir)
-{
- if(raw_pkt->meta[0]!= NULL || (raw_pkt->meta[1]!= NULL))
- {
- struct rawpkt_metadata *snd_meta = NULL;
- if(raw_pkt->meta[route_dir]!=NULL)
- {
- snd_meta=raw_pkt->meta[route_dir];
- }
- else // failover
- {
- snd_meta=raw_pkt->meta[route_dir^1];
- }
- if(ptr_marsio_buff_set_metadata)
- {
- ptr_marsio_buff_set_metadata((marsio_buff_t *)send_pkt_io_reference, MR_BUFF_ROUTE_CTX, (void *)snd_meta->data, snd_meta->sz_data);
- }
- if(ptr_marsio_buff_set_sid_list)
- {
- ptr_marsio_buff_set_sid_list((marsio_buff_t *)send_pkt_io_reference, snd_meta->raw_sid_list.sid_list, snd_meta->raw_sid_list.sz_sidlist);
- }
- marsio_update_sid_list(raw_pkt, send_pkt_io_reference);
- }
-
- return;
-}
-
-void marsio_dl_io_free_rawpkt_meta(struct rawpkt_metadata * meta, int thread_seq)
-{
- if(meta != NULL)
- {
- sapp_mem_free(SAPP_MEM_DYN_SID_LIST, thread_seq,meta);
- meta=NULL;
- }
- return;
-}
-
-
-void *marsio_dl_io_get_send_handle(int thread_seq)
-{
- return (void *)&g_mario4_io_handle[thread_seq];
-}
-
-
-int marsio_dl_io_get_version(void)
-{
- return g_marsio4_version_VERSION;
-}
-
-int marsio_dl_io_register_cb(PACKET_IO_CB_T fun)
-{
- g_marsio4_work_fun = fun;
- return 0;
-}
-
-int marsio_dl_io_send_only_thread_init(void)
-{
- if(sapp_global_val->config.cpu.bind_mask_array_num > 0){
- ptr_marsio_thread_init(sapp_marsio4_instance);
- }
-
- return 0;
-}
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-static int tmp_vdevice_num;
-static char **tmp_vdevice_name; /* �����豸�����б�, ��pag.conf�еIJ����豸, ��������Ӧ��ģʽ��ע */
-static struct mr_sendpath **tmp_vdevice_sendpath;
-void * marsio_dl_io_device_alias(unsigned int target_id, char *device_args)
-{
- int i;
- int len1, len2;
-
- len1 = strlen(device_args);
-
- for(i = 0; i < g_mr4_device_num; i++){
- len2 = strlen(g_mr4_up_device_name[i]);
- /* ʹ������ַ��Ƚ�, ��ֹ"eth12", "eth1"�Ƚϵ���ȵ�BUG */
- if(strncasecmp(device_args, g_mr4_up_device_name[i], MAX(len1, len2)) == 0){
- return (void *)g_mr4_sendpath_up_set[i];
- }
- }
-
- if(NULL != g_mr4_down_device_name){
- for(i = 0; i < g_mr4_device_num; i++){
- len2 = strlen(g_mr4_down_device_name[i]);
- /* ʹ������ַ��Ƚ�, ��ֹ"eth12", "eth1"�Ƚϵ���ȵ�BUG */
- if(strncasecmp(device_args, g_mr4_down_device_name[i], MAX(len1, len2)) == 0){
- return (void *)g_mr4_sendpath_down_set[i];
- }
- }
- }
-
- /* �˿�δ��pag.conf��ע��, �����������豸����, �ֳ��򿪷��;�� */
- struct mr_vdev *t_vdev;
- struct mr_sendpath *t_sendpath;
-
- for(i = 0; i < tmp_vdevice_num; i++){
- len2 = strlen(tmp_vdevice_name[i]);
- /* ʹ������ַ��Ƚ�, ��ֹ"eth12", "eth1"�Ƚϵ���ȵ�BUG */
- if(strncasecmp(device_args, tmp_vdevice_name[i], MAX(len1, len2)) == 0){
- return (void *)tmp_vdevice_sendpath[i];
- }
- }
- /* û�ҵ�, ���豸, ���洢���;�� */
- if(0 == tmp_vdevice_num){
- tmp_vdevice_name = (char **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,sizeof(void *));
- tmp_vdevice_sendpath = (struct mr_sendpath **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,sizeof(void *));
- }else{
- tmp_vdevice_name = (char **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,tmp_vdevice_name, sizeof(void *) * (tmp_vdevice_num + 1));
- tmp_vdevice_sendpath = (struct mr_sendpath **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,tmp_vdevice_sendpath, sizeof(void *) * (tmp_vdevice_num + 1));
- }
- tmp_vdevice_name[tmp_vdevice_num] = sapp_strdup(device_args);
-
- t_vdev = ptr_marsio_open_device(sapp_marsio4_instance, device_args,
- 0,
- g_marsio4_work_thread_num);
- if(NULL == t_vdev){
- printf("\033[41m[Error]Can't open device '%s'!\033[0m\n", device_args);
- return NULL;
- }
- t_sendpath = ptr_marsio_sendpath_create_by_vdev(t_vdev);
- tmp_vdevice_sendpath[tmp_vdevice_num] = t_sendpath;
- tmp_vdevice_num++; /* �����¼����� */
-
- return t_sendpath;
-}
-
-/************************ funcitons for dynamic link *************************/
-
-/*
- ����һ�������������˶��ٸ�bit��1��.
-*/
-static inline int calc_integer_bit_num(unsigned long long num)
-{
- int i = 0;
- int bit_num = 0;
-
- for(i = 0; i < (int)sizeof(long long) * 8; i++){
- if(num & 1){
- bit_num++;
- }
- num = num >> 1;
- if(0 == num){ /* num�Ѿ���0��, ��û��Ҫ���жϺ���bitλ�� */
- break;
- }
- }
-
- return bit_num;
-}
-
-static int marsio4_pkt_forward_for_gdev_mode(int tid, struct mr_sendpath * sendpath, marsio_buff_t * mbuf)
-{
- char tmp_mac[6];
- struct mesa_ethernet_hdr *eth_hdr = (struct mesa_ethernet_hdr *)ptr_marsio_buff_mtod(mbuf);
-
- /* ����Դ��Ŀ��MAC��ַ, �ٰ�ԭʼ����ע��GDEV */
- memcpy(tmp_mac, eth_hdr->ether_shost, 6);
- memcpy(eth_hdr->ether_shost, eth_hdr->ether_dhost, 6);
- memcpy(eth_hdr->ether_dhost, tmp_mac, 6);
-
- return ptr_marsio_send_burst(sendpath, tid, &mbuf, 1);
-}
-
-static int marsio4_pkt_forward(int tid, struct mr_sendpath * sendpath, marsio_buff_t * mbufs)
-{
- int ret = 0;
- struct mr_tunnat_ctrlzone *ctrl_zone;
-
- ctrl_zone = (struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone(mbufs, 0);
-
- /* ������ȡ, ���������������, vxlan��������װģʽ����ʹ��, Ҫ��ÿ��mbuf�жϵײ��װģʽ */
- if((ctrl_zone->action & TUNNAT_CZ_ACTION_FORWARD)
- || (0 != sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support)){
- /* 20201010 lijia modify, ����overlay��mrtunnat��ģʽ��, ctrl_zone�ǿ�, Ĭ�϶���ע */
- /* 20190409 lijia modify, tunnel mode, ��������װ�İ����ܻ�ע */
- /* vxlan��װ�ڲ�����ת���������κβ���, ֱ�ӵ���marsio_send_burst, ��marsio�������� */
- ctrl_zone->action = TUNNAT_CZ_ACTION_FORWARD;
- ptr_marsio_buff_ctrlzone_set(mbufs, 0, ctrl_zone, sizeof(struct mr_tunnat_ctrlzone));
- ret = ptr_marsio_send_burst(sendpath, tid, &mbufs, 1);
-
- marsio_pkt_dump(tid, mbufs, PKT_CLASSIFY_FORWARD);
- }
- else
- {
- ret = -1;
- }
- return ret;
-}
-
-
-static inline int marsio4_pkt_hand(int tid, marsio_buff_t *rx_buff, raw_pkt_t *raw_pkt, unsigned char dir)
-{
- int ret;
-
- raw_pkt->__lib_raw_pkt_data = ptr_marsio_buff_mtod(rx_buff);
- raw_pkt->raw_pkt_data = raw_pkt->__lib_raw_pkt_data;
- raw_pkt->__lib_raw_pkt_len = ptr_marsio_buff_datalen(rx_buff);
- raw_pkt->raw_pkt_len = raw_pkt->__lib_raw_pkt_len;
- raw_pkt->io_lib_pkt_reference = rx_buff;
- /* ˫��ģʽdir��������internal, external����,
- inlineģʽ��ʱ��dir������, ���ջ��� packet_io_hook_input_vxlan() ,ͨ��vxlan header����routedir .
- */
- raw_pkt->route_dir = dir;
-
- if(unlikely(g_marsio_have_bpf == 1))
- {
- if (0 == bpf_filter(MARSIO_BPF_FILTER[tid].bf_insns,
- (const unsigned char *)raw_pkt->raw_pkt_data,
- raw_pkt->raw_pkt_len, raw_pkt->raw_pkt_len))
- {
- g_marsio_bpf_counter[tid].count++;
- return DROP;
- }
- }
-
- if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){
- struct mr_tunnat_ctrlzone *mr_ctrlzone = (struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone(rx_buff, 0); /* index */
- raw_pkt->is_overlay_pkt = mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD;
- }else{
- if(OVERLAY_MODE_NF == sapp_global_val->config.packet_io.packet_io_tunnel.overlay_mode_bin)
- {
- raw_pkt->is_overlay_pkt = 1;
- }
- else
- {
- raw_pkt->is_overlay_pkt = 0; /* ��mrtunnatʱ, ���յ�������ȷ��, ��packet_io_hook�����Ƿ���overlay�İ� */
- }
- }
-
- /* clear pkt status */
- raw_pkt->diagnose_error_to_dump = 0;
- raw_pkt->vlan_flipping_couple[0] = 0;
- raw_pkt->vlan_flipping_couple[1] = 0;
- raw_pkt->overlay_layer_bytes = 0;
- raw_pkt->drop_current_pkt_flag = 0;
- raw_pkt->d_pkt = NULL;
-
- //ret = (*g_marsio4_work_fun)((const raw_pkt_t *)raw_pkt, mr_ctrlzone->route_dir, tid);
- ret = (*g_marsio4_work_fun)((const raw_pkt_t *)raw_pkt, dir, tid);
-
- return ret;
-}
-
-static int marsio4_process_packet(int tid, raw_pkt_t *raw_pkt)
-{
- int i,j,k, pkt_num = 0;
- marsio_buff_t * rx_buff[MARSIO_BURST_PKT_MAX]; /* ����豸֮���Ǵ��л�ȡ, ̫�������ܵ�, ̫���������ʱ�� */
- int rcv_res, hand_res;
-
- if((__NET_CONN_PARALLEL & g_marsio4_topology_mode) != 0){
- for(i = 0; i < g_mr4_device_num; i++){
- rcv_res = ptr_marsio_recv_burst(g_mr4_dev_up_handle_set[i], tid, rx_buff, marsio4_burst_process_pkt_num);
- if(rcv_res > 0){
- raw_pkt->device_index = i;
- __builtin_prefetch(ptr_marsio_buff_mtod(rx_buff[0]));
-
- for(j = 0, k = 1; j < rcv_res; j++, k++){
- if(k < rcv_res) {
- __builtin_prefetch(ptr_marsio_buff_mtod(rx_buff[k]));
- }
-
- marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_UP); /* ����ģʽ�����ķ���ֵ */
- }
- pkt_num += rcv_res;
- ptr_marsio_buff_free(sapp_marsio4_instance, rx_buff, rcv_res, MARSIO_SOCKET_ID_ANY, tid); /* �������漰����, ������ҵ����������free */
- }
- }
- }else if(NET_CONN_SERIAL_GDEV == g_marsio4_topology_mode){
- for(i = 0; i < g_mr4_device_num; i++){
- rcv_res = ptr_marsio_recv_burst(g_mr4_dev_up_handle_set[i], tid, rx_buff, 16);
- if(rcv_res > 0){
- for(j = 0; j < rcv_res; j++){
- raw_pkt->device_index = i;
- hand_res = marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_UP); /* ��marsio4_pkt_hand()����dir */
- if ((g_marsio4_topology_mode & __NET_CONN_SERIAL) && (PASS == hand_res))
- {
- /* NOTE:
- MARSIO����ģʽ������, �����������հ�, ��Ҫͨ������������ע��,
- */
- marsio_update_sid_list(raw_pkt, rx_buff[j]);
- int ret = marsio4_pkt_forward(tid, g_mr4_sendpath_up_set[i], rx_buff[j]);
- if (ret < 0)
- {
- ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
- }
- }
- else if (hand_res == DROP)
- {
- /* ����ģʽ��ֻ�ܵ���free, �п���batch�յ�N������, ij������Ҫ��ע, ij��������Ҫ */
- ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
- }
- else
- ;
- }
- pkt_num += rcv_res;
- }
- }
- }else if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
- for(i = 0; i < g_mr4_device_num; i++){
- rcv_res = ptr_marsio_recv_burst(g_mr4_dev_up_handle_set[i], tid, rx_buff, marsio4_burst_process_pkt_num);
- if(rcv_res > 0){
- for(j = 0; j < rcv_res; j++){
- hand_res = marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_UP);
- if((g_marsio4_topology_mode & __NET_CONN_SERIAL) && (PASS == hand_res)){
- //marsio4_pkt_forward(tid, rx_buff[j]);
- ptr_marsio_send_burst(g_mr4_sendpath_down_set[i], tid, &rx_buff[j], 1);
- }else{
- /* ����ģʽ�µ���free, �п�����Ҫ��ע/���� */
- ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
- }
- }
- pkt_num += rcv_res;
- }
- rcv_res = ptr_marsio_recv_burst(g_mr4_dev_down_handle_set[i], tid, rx_buff, marsio4_burst_process_pkt_num);
- if(rcv_res > 0){
- for(j = 0; j < rcv_res; j++){
- hand_res = marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_DOWN);
- if((g_marsio4_topology_mode & __NET_CONN_SERIAL) && (PASS == hand_res)){
- //marsio4_pkt_forward(tid, rx_buff[j]);
- ptr_marsio_send_burst(g_mr4_sendpath_up_set[i], tid, &rx_buff[j], 1);
- }else{
- /* ����ģʽ�µ���free, �п�����Ҫ��ע/���� */
- ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
- }
- }
- pkt_num += rcv_res;
- }
- }
- }
-
- return pkt_num;
-}
-
-static int marsio4_sleep_time_table[100] =
-{
- 5, 5, 5, 5, 5, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-
-static inline void marsio4_sleep(int tot_call_times, int rcv_pkt_times)
-{
- float work_percent = ((float)rcv_pkt_times/(float)tot_call_times) * 100.0;
-
- if((work_percent < 90.0) && (marsio4_sleep_time_table[(int)work_percent] > 0)){
- sapp_usleep(marsio4_sleep_time_table[(int)work_percent]);
- }
-}
-
-/* ������ģʽ��, marsio�����л���, ���°�����ʱ��Ҫ����ˢ�¶����е����� */
-static inline void marsio4_flush_queue_buf(int tid)
-{
- int i;
-
- if(NULL == ptr_marsio_send_burst_flush){
- return;
- }
-
- for(i = 0; i < g_mr4_device_num; i++){
- ptr_marsio_send_burst_flush(g_mr4_sendpath_up_set[i], tid);
-
- if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
- ptr_marsio_send_burst_flush(g_mr4_sendpath_down_set[i], tid);
- }
- }
-}
-
-static void *marsio4_worker(void *arg)
-{
- int tseq = *((int *)arg);
- raw_pkt_t raw_pkt;
- int total_call_times = 0, rcv_pkt_tims = 0, polling_work_times = 0;
-
- char thread_name[32] = "";
- sprintf(thread_name, "sapp_marsio_%d", tseq);
- prctl(PR_SET_NAME, thread_name);
-
- if(sapp_global_val->config.cpu.bind_mask_array_num > 0){
- ptr_marsio_thread_init(sapp_marsio4_instance);
- sapp_global_val->individual_fixed.cpu_bind_core_id_per_thread[tseq] = get_current_thread_cpu_affinity_id();
- }
- sapp_global_val->individual_fixed.thread_tid[tseq] = syscall(SYS_gettid);
-
- sapp_runtime_log(RLOG_LV_FATAL, "pid:%d, thread_index:%d, TID(LWP):%ld, PSR:%d",
- getpid(), tseq,
- sapp_global_val->individual_fixed.thread_tid[tseq],
- sapp_global_val->individual_fixed.cpu_bind_core_id_per_thread[tseq]);
-
- memset(&raw_pkt, 0, sizeof(raw_pkt_t));
-
- /* �̶�����IJ���Ԥ������ */
- raw_pkt.low_layer_type = (enum addr_type_t)g_marsio4_cap_level;
- raw_pkt.magic_num = RAW_PKT_MAGIC_NUM;
- raw_pkt.offset_to_raw_pkt_hdr = 0;
-
- while(SAPP_STATE_PROCESSING != sapp_get_current_state()){
- sapp_usleep(1000);
- }
-
- /* for perf optimize
- Ƶ������stream_process_polling()�Ⱥ���, �˴����ں����ⲿ�ж�һ���Ƿ���Ҫ����.
- */
- int polling_enabled = sapp_global_val->config.packet_io.polling_enabled;
- int infinite_loop_enabled = sapp_global_val->config.packet_io.infinite_loop_enabled;
- while(SAPP_STATE_PROCESSING == sapp_global_val->individual_volatile->current_state){
- if(marsio4_process_packet(tseq, &raw_pkt) > 0){
- rcv_pkt_tims++;
- }else{
- marsio4_flush_queue_buf(tseq);
- /* �ް�ʱҪ����polling�ӿ� */
- if(polling_enabled && ((stream_process_polling(tseq) & POLLING_STATE_WORK) != 0)){
- polling_work_times++;
- }
- if(polling_enabled && (polling_stream_timeout(tseq) & POLLING_STATE_WORK)){
- polling_work_times++;
- }
- }
-
- sapp_global_val->mthread_volatile[tseq]->sys_stat.count[SAPP_STAT_FETCH_PKT]++;
- total_call_times++;
-
- if((rcv_pkt_tims % sapp_global_val->config.packet_io.polling_priority) == 0){
- /* ��������޴�, һֱ�а�ʱ, ÿ��polling_priority����ҲҪ����polling�ӿ� */
- if(polling_enabled && ((stream_process_polling(tseq) & POLLING_STATE_WORK) != 0)){
- polling_work_times++;
- }
- total_call_times++;
- }
-
- if(total_call_times >= 100){
- if(likely(infinite_loop_enabled == 0))
- {
- marsio4_sleep(total_call_times, rcv_pkt_tims + polling_work_times);
- }
- total_call_times = 0;
- rcv_pkt_tims = 0;
- polling_work_times = 0;
- }
- }
- return NULL;
-}
-
-static void fake_marsio_buff_set_rehash_index(marsio_buff_t *m, uint32_t hash)
-{
- return ;
-}
-
-static int marsio_dl_get_function_entry(void)
-{
- marsio_so_handle = dlopen(ABBR_MARSIO_LIBRARY_FILE, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
- if(NULL == marsio_so_handle){
- printf("\033[1;31;40m[Error]dlopen '%s' failed, %s\033[0m\n", ABBR_MARSIO_LIBRARY_FILE, dlerror());
- return -1;
- }
-
- ptr_marsio_option_set = (int (*)(struct mr_instance * instance, marsio_opt_type_t opt_type, void * opt, size_t sz_opt))dlsym(marsio_so_handle, "marsio_option_set");
- if(NULL == ptr_marsio_option_set){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_option_set", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_create = (struct mr_instance * (*)(void))dlsym(marsio_so_handle, "marsio_create");
- if(NULL == ptr_marsio_create){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_create", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_close_device = (void (*)(struct mr_vdev *vdev))dlsym(marsio_so_handle, "marsio_close_device");
- if(NULL == ptr_marsio_close_device){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_close_device", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_init = (int (*)(struct mr_instance * instance, const char * appsym))dlsym(marsio_so_handle, "marsio_init");
- if(NULL == ptr_marsio_init){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_init", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_open_device = (struct mr_vdev * (*)(struct mr_instance * instance, const char * devsym, unsigned int nr_rxstream, unsigned int nr_txstream))dlsym(marsio_so_handle, "marsio_open_device");
- if(NULL == ptr_marsio_open_device){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_open_device", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_sendpath_create_by_vdev = (struct mr_sendpath * (*)(struct mr_vdev * dest_device))dlsym(marsio_so_handle, "marsio_sendpath_create_by_vdev");
- if(NULL == ptr_marsio_sendpath_create_by_vdev){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_sendpath_create_by_vdev", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_sendpath_destory = (void (*)(struct mr_sendpath * sendpath))dlsym(marsio_so_handle, "marsio_sendpath_destory");
- if(NULL == ptr_marsio_sendpath_create_by_vdev){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_sendpath_destory", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_thread_init = (int (*)(struct mr_instance * instance))dlsym(marsio_so_handle, "marsio_thread_init");
- if(NULL == ptr_marsio_thread_init){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_thread_init", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_recv_burst = (int (*)(struct mr_vdev * vdev, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs))dlsym(marsio_so_handle, "marsio_recv_burst");
- if(NULL == ptr_marsio_recv_burst){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_recv_burst", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_send_burst = (int (*)(struct mr_sendpath * sendpath, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs))dlsym(marsio_so_handle, "marsio_send_burst");
- if(NULL == ptr_marsio_send_burst){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_send_burst", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_send_burst_with_options = (int (*)(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[], int nr_mbufs, uint16_t options))dlsym(marsio_so_handle, "marsio_send_burst_with_options");
- if(NULL == ptr_marsio_send_burst_with_options){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_send_burst_with_options", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_free = (void (*)(struct mr_instance * instance, marsio_buff_t *marsio_buff[],unsigned int nr_mbufs, int socket_id, int thread_id))dlsym(marsio_so_handle, "marsio_buff_free");
- if(NULL == ptr_marsio_buff_free){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_free", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_malloc_global = (int (*)(struct mr_instance * instance, marsio_buff_t *marsio_buff[], unsigned int nr_mbufs, int socket_id, int thread_id))dlsym(marsio_so_handle, "marsio_buff_malloc_global");
- if(NULL == ptr_marsio_buff_malloc_global){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_malloc_global", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_append = (char * (*)(marsio_buff_t *m, uint16_t len))dlsym(marsio_so_handle, "marsio_buff_append");
- if(NULL == ptr_marsio_buff_append){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_append", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_ctrlzone = (void * (*)(marsio_buff_t *m, uint8_t id))dlsym(marsio_so_handle, "marsio_buff_ctrlzone");
- if(NULL == ptr_marsio_buff_ctrlzone){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_ctrlzone", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_ctrlzone_set = (void (*)(marsio_buff_t *m, uint8_t id, void* ptr_data, uint8_t size))dlsym(marsio_so_handle, "marsio_buff_ctrlzone_set");
- if(NULL == ptr_marsio_buff_ctrlzone_set){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_ctrlzone_set", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_set_rehash_index = (void (*)(marsio_buff_t *m, uint32_t hash))dlsym(marsio_so_handle, "marsio_buff_set_rehash_index");
- if(NULL == ptr_marsio_buff_set_rehash_index){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_set_rehash_index", ABBR_MARSIO_LIBRARY_FILE);
- ptr_marsio_buff_set_rehash_index = fake_marsio_buff_set_rehash_index;
- //return -1;
- }
-
- ptr_marsio_buff_mtod = (char * (*)(marsio_buff_t *m))dlsym(marsio_so_handle, "marsio_buff_mtod");
- if(NULL == ptr_marsio_buff_mtod){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_mtod", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_datalen = (uint32_t (*)(marsio_buff_t *m))dlsym(marsio_so_handle, "marsio_buff_datalen");
- if(NULL == ptr_marsio_buff_datalen){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_datalen", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_buflen = (uint32_t (*)(marsio_buff_t *m))dlsym(marsio_so_handle, "marsio_buff_buflen");
- if(NULL == ptr_marsio_buff_buflen){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_buflen", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- ptr_marsio_buff_clone_with_options = (marsio_buff_t * (*)(struct mr_instance * instance, marsio_buff_t * md, int socket_id, int thread_id, uint16_t options))dlsym(marsio_so_handle, "marsio_buff_clone_with_options");
- if(NULL == ptr_marsio_buff_clone_with_options){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_clone_with_options", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- /************* note: û��marsio_send_burst_flush()�����������, ������! *****************/
- ptr_marsio_send_burst_flush = (void (*)(struct mr_sendpath * sendpath, queue_id_t sid))dlsym(marsio_so_handle, "marsio_send_burst_flush");
- if(NULL == ptr_marsio_send_burst_flush){
- printf("\033[33m[Warning]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_send_burst_flush", ABBR_MARSIO_LIBRARY_FILE);
- //go on
- }
-
- ptr_marsio_buff_malloc_smartoffload = (marsio_buff_t * (*)(struct mr_vdev *vdev, const char *pkt, unsigned int pkt_len))dlsym(marsio_so_handle, "marsio_buff_malloc_smartoffload");
- if(NULL == ptr_marsio_buff_malloc_smartoffload){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_malloc_smartoffload", ABBR_MARSIO_LIBRARY_FILE);
- sleep(1);
- }
-
- /* for vlan flipping */
- if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
- ptr_marsio_buff_get_metadata = (int (*)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data))dlsym(marsio_so_handle, "marsio_buff_get_metadata");
- if(NULL == ptr_marsio_buff_get_metadata){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_get_metadata", ABBR_MARSIO_LIBRARY_FILE);
- //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
- sleep(1);
- }
-
- ptr_marsio_buff_set_metadata = (int (*)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data))dlsym(marsio_so_handle, "marsio_buff_set_metadata");
- if(NULL == ptr_marsio_buff_set_metadata){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_set_metadata", ABBR_MARSIO_LIBRARY_FILE);
- //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
- sleep(1);
- }
-
- ptr_marsio_buff_get_sid_list = (int (*)(marsio_buff_t *m, uint16_t * out_slist, uint8_t sz_out_slist))dlsym(marsio_so_handle, "marsio_buff_get_sid_list");
- if(NULL == ptr_marsio_buff_set_metadata){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_get_sid_list", ABBR_MARSIO_LIBRARY_FILE);
- //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
- sleep(1);
- }
- ptr_marsio_buff_set_sid_list = (int (*)(marsio_buff_t *m, uint16_t * slist, uint8_t sz_slist))dlsym(marsio_so_handle, "marsio_buff_set_sid_list");
- if(NULL == ptr_marsio_buff_set_metadata){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_set_sid_list", ABBR_MARSIO_LIBRARY_FILE);
- //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
- sleep(1);
- }
-
- ptr_marsio_buff_append_sid_list = (int (*)(marsio_buff_t *m, uint16_t * slist, uint8_t sz_slist))dlsym(marsio_so_handle, "marsio_buff_append_sid_list");
- if(NULL == ptr_marsio_buff_append_sid_list){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_append_sid_list", ABBR_MARSIO_LIBRARY_FILE);
- //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
- sleep(1);
- }
-
- ptr_marsio_buff_prepend_sid_list = (int (*)(marsio_buff_t *m, uint16_t * slist, uint8_t sz_slist))dlsym(marsio_so_handle, "marsio_buff_prepend_sid_list");
- if(NULL == ptr_marsio_buff_prepend_sid_list){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_prepend_sid_list", ABBR_MARSIO_LIBRARY_FILE);
- //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
- sleep(1);
- }
-
- ptr_marsio_buff_unset_metadata = (int (*)(marsio_buff_t *m, enum mr_buff_metadata_type type))dlsym(marsio_so_handle, "marsio_buff_unset_metadata");
- if(NULL == ptr_marsio_buff_unset_metadata){
- printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_unset_metadata", ABBR_MARSIO_LIBRARY_FILE);
- //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
- sleep(1);
- }
- }
-
- ptr_marsio_destory = (int (*)(struct mr_instance *instance))dlsym(marsio_so_handle, "marsio_destory");
- if(NULL == ptr_marsio_destory){
- printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_destory", ABBR_MARSIO_LIBRARY_FILE);
- return -1;
- }
-
- return 0;
-}
-
-int marsio_send_burst_with_options_for_tcpdumpmesa(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[],
- int nr_mbufs, uint16_t options)
-{
- raw_pkt_t rawpkt;
- char *rawpkt_data;
- uint32_t rawpkt_len;
-
- if(G_PKT_DUMP_SW != 0){
- rawpkt_data = ptr_marsio_buff_mtod(mbufs[0]);
- rawpkt_len = ptr_marsio_buff_buflen(mbufs[0]);
- rawpkt.magic_num = RAW_PKT_MAGIC_NUM;
- rawpkt.low_layer_type = ADDR_TYPE_MAC;
- rawpkt.raw_pkt_data = rawpkt_data;
- rawpkt.raw_pkt_len = rawpkt_len;
- rawpkt.__lib_raw_pkt_data = rawpkt_data;
- rawpkt.__lib_raw_pkt_len = rawpkt_len;
-
- cycle_pkt_dump_by_classify(sid, &rawpkt, PKT_CLASSIFY_INJECT);
- }
-
- return ptr_marsio_send_burst_with_options(sendpath, sid, mbufs, nr_mbufs, options);
-}
-
-
-unsigned int marsio_get_vlan_id_from_mbuff(void *pkt_reference)
-{
- unsigned int vlan_id = 0;
-
- if(ptr_marsio_buff_get_metadata){
- ptr_marsio_buff_get_metadata((marsio_buff_t *)pkt_reference, MR_BUFF_METADATA_VLAN_TCI, &vlan_id, sizeof(int));
- }
-
- return vlan_id;
-}
-
-int marsio_get_route_dir_from_mbuff(void *pkt_reference)
-{
- int dir = -1;
-
- if(ptr_marsio_buff_get_metadata){
- ptr_marsio_buff_get_metadata((marsio_buff_t *)pkt_reference, MR_BUFF_DIR, &dir, sizeof(int));
- }
-
- return dir;
-}
-
-
-int marsio_set_vlan_id_to_mbuff(void *pkt_reference, unsigned int vlan_id_host_order)
-{
- int ret = 0;
- if(ptr_marsio_buff_set_metadata){
- ret = ptr_marsio_buff_set_metadata((marsio_buff_t *)pkt_reference, MR_BUFF_METADATA_VLAN_TCI, &vlan_id_host_order, sizeof(int));
- }
-
- return ret;
-}
-
-
-int marsio_dl_io_init(int argc, char *argv[])
-{
- int i, ret;
- char app_name[32];
- int max_send_queue_num;
-
- if(marsio_dl_get_function_entry() < 0){
- printf("\033[1;31;40m[Error]dlopen marsio.so symbol failed!\033[0m\n");
- return -1;
- }
-
- sapp_marsio4_instance = ptr_marsio_create();
- if(NULL == sapp_marsio4_instance) {
- fprintf(stderr,"%s\n","marsio_create error!\n");
- return -1;
- }
-
- if(NET_CONN_SERIAL_GDEV == g_marsio4_topology_mode){
- if(g_mr4_device_num != 1){
- printf("\033[1;31;40m[Error] in inline mode, capture device num is %d!\033[0m\n", g_mr4_device_num);
- return -1;
- }
- }else if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
- if(g_mr4_device_num != 1){
- printf("\033[1;31;40m[Error] in transparent mode, capture device num is %d!\033[0m\n", g_mr4_device_num);
- return -1;
- }
- }
-
- g_mario4_io_handle = (marsio4_io_handle *)SAPP_GLOBAL_ALLOC(sizeof(marsio4_io_handle) * g_marsio4_work_thread_num);
- ptr_marsio_option_set(sapp_marsio4_instance, MARSIO_OPT_THREAD_NUM, &g_marsio4_work_thread_num, sizeof(int));
-
- if(sapp_global_val->config.cpu.bind_mask_array_num > 0){
- cpu_set_t cpu_mask;
- CPU_ZERO(&cpu_mask);
- for (i = 0; i < sapp_global_val->config.cpu.bind_mask_array_num; i++)
- {
- CPU_SET(sapp_global_val->config.cpu.bind_mask_array[i], &cpu_mask);
- }
- ret = ptr_marsio_option_set(sapp_marsio4_instance, MARSIO_OPT_THREAD_MASK_IN_CPUSET, &cpu_mask, sizeof(cpu_mask));
- if (ret < 0)
- {
- printf("\033[1;31;40m[Error] marsio set CPU->bind_mask failed!\033[0m\n");
- return -1;
- }
- }
-
- ptr_marsio_init(sapp_marsio4_instance, sapp_global_val->config.system.instance_name);
-
- g_mr4_dev_up_handle_set = (struct mr_vdev **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
- g_mr4_dev_down_handle_set = (struct mr_vdev **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
- g_mr4_sendpath_up_set = (struct mr_sendpath **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
- g_mr4_sendpath_down_set = (struct mr_sendpath **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
-
- max_send_queue_num = sapp_global_val->config.cpu.worker_threads + sapp_global_val->config.cpu.send_only_threads_max_num;
-
- for(i = 0; i < g_mr4_device_num; i++){
- g_mr4_dev_up_handle_set[i] = ptr_marsio_open_device(sapp_marsio4_instance, g_mr4_up_device_name[i],
- g_marsio4_work_thread_num,
- max_send_queue_num);
- if(NULL == g_mr4_dev_up_handle_set[i]){
- printf("\033[1;31;40m[Error]Open device '%s' error, please check sapp.toml->packet_io.interface!\033[0m\n",
- g_mr4_up_device_name[i]);
- return -1;
- }
- g_mr4_sendpath_up_set[i] = ptr_marsio_sendpath_create_by_vdev(g_mr4_dev_up_handle_set[i]);
-
- if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
- g_mr4_dev_down_handle_set[i] = ptr_marsio_open_device(sapp_marsio4_instance, g_mr4_down_device_name[i],
- g_marsio4_work_thread_num,
- max_send_queue_num);
- if(NULL == g_mr4_dev_down_handle_set[i]){
- printf("\033[1;31;40m[Error]Open device '%s' error, please check sapp.toml->packet_io.interface!\033[0m\n",
- g_mr4_up_device_name[i]);
- return -1;
- }
- g_mr4_sendpath_down_set[i] = ptr_marsio_sendpath_create_by_vdev(g_mr4_dev_down_handle_set[i]);
- }
- }
-
- return 0;
-}
-
-void marsio_dl_io_run(void)
-{
- int i = 0, ret;
-
- for(i = 0; i < g_marsio4_work_thread_num; i++)
- {
- marsio4_work_thread_seq[i] = i;
- ret = pthread_create(&(marsio4_work_tid[i]), NULL, marsio4_worker, (void *) &(marsio4_work_thread_seq[i]));
- assert(0 == ret);
- sapp_global_val->individual_fixed.thread_obtain_id[i] = marsio4_work_tid[i];
- }
-}
-
-void marsio_dl_io_destroy(void)
-{
- int i;
-
- for(i = 0; i < g_mr4_device_num; i++){
- ptr_marsio_close_device(g_mr4_dev_up_handle_set[i]);
- ptr_marsio_sendpath_destory(g_mr4_sendpath_up_set[i]);
- if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
- ptr_marsio_close_device(g_mr4_dev_down_handle_set[i]);
- ptr_marsio_sendpath_destory(g_mr4_sendpath_down_set[i]);
- }
- }
-
- SAPP_GLOBAL_FREE(g_mr4_dev_up_handle_set);
- SAPP_GLOBAL_FREE(g_mr4_sendpath_up_set);
- SAPP_GLOBAL_FREE(g_mr4_dev_down_handle_set);
- SAPP_GLOBAL_FREE(g_mr4_sendpath_down_set);
-
- SAPP_GLOBAL_FREE(g_mario4_io_handle);
- g_mr4_device_num = 0;
-
- ptr_marsio_destory(sapp_marsio4_instance);
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sapp_api.h"
+#include "sapp_private_api.h"
+#include "sapp_declaration.h"
+#include <assert.h>
+
+/*
+ netconnection_mode:
+ 1: ���������ղ���
+ 2: һ�����鿨, ˫��˫��
+ 3: һ��һ�鿨, ��������
+
+
+ TODO 1:
+ ��send_raw_pkt.conf���������ݴ洢��G_SND_RAW_PKT_INFO,
+ ��ģ���䲻һ������Щ�����հ�, ���϶������Щ��������, ����ע�����ݰ�����Ӧ�õ���������,
+ ��ȻҪ�ڳ�ʼ��ʱ����Щ�豸, ����send_path.
+*/
+typedef struct{
+ int thread_seq;
+ void *send_mbuf_mtod_ptr;
+ marsio_buff_t *send_mbuf[1];
+ struct mr_vdev *dev_up, *dev_down; /* GDEVģʽ��, ֱ��ʹ��dev_up[0]; ͬʱ����˫��������ģʽ */
+ struct mr_sendpath *sendpath_up, *sendpath_down; /* ����ģʽ��, ֱ��ʹ��sendpath_up; ͬʱ����˫��������ģʽ */
+}marsio4_io_handle;
+
+
+
+
+#ifndef MAX_METADATA_LEN
+#define MAX_METADATA_LEN 16
+#endif
+
+struct rawpkt_metadata
+{
+ char data[MAX_METADATA_LEN];
+ unsigned int sz_data;
+ struct segment_id_list raw_sid_list;
+};
+
+extern int marsio_buff_get_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
+extern int marsio_buff_set_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
+extern int marsio_buff_unset_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type);
+/*
+ ������ͬʱ, ��tcpdump_mesaһ��, ���ڲ�������,
+ ��ע�İ�����tcpdump_mesa����, ֱ���������ײ㲶�񼴿�.
+*/
+extern void cycle_pkt_dump_by_classify(int thread_seq, const raw_pkt_t *p_raw_pkt, enum _pkt_classify class_val);
+extern int G_PKT_DUMP_SW;
+
+
+int g_marsio4_version_VERSION_20190907;
+int g_marsio4_version_VERSION = 20190907;
+static PACKET_IO_CB_T g_marsio4_work_fun;
+static int g_marsio4_work_thread_num = 1;
+static int g_marsio4_cap_level = CAP_LEVEL_MAC;
+static int g_marsio4_topology_mode = NET_CONN_PARALLEL;
+static int marsio4_work_thread_seq[MAX_THREAD_NUM];
+static pthread_t marsio4_work_tid[MAX_THREAD_NUM];
+extern int g_use_MESA_sleep_sw;
+struct mr_instance * sapp_marsio4_instance = NULL; /* ��ʱ���⿪��,������Ϊstatic */
+static int g_mr4_device_num = 0;
+static char **g_mr4_up_device_name; /* �豸���Ƽ���, meth0, meth1, meth2... */
+static char **g_mr4_down_device_name; /* �豸���Ƽ���, meth0, meth1, meth2... */
+static struct mr_vdev **g_mr4_dev_up_handle_set, **g_mr4_dev_down_handle_set; /* �豸������� */
+static struct mr_sendpath **g_mr4_sendpath_up_set, **g_mr4_sendpath_down_set; /* ����·��(���)���� */
+static marsio4_io_handle *g_mario4_io_handle;
+static void *marsio_so_handle;
+
+#define MARSIO_BURST_PKT_MAX (256)
+static int marsio4_burst_process_pkt_num = 32; /* ������������, ��pag.conf�л�ȡ */
+//static long marsio4_thread_bind_mask = 0;
+#define TIME_DELAY_MONITOR (0) /* ����������ʱ��� */
+
+extern void timestamp_region_update_driver(int tid, long long cpu_cycle);
+extern int stream_process_polling(int thread_seq);
+
+/* dlopen funtion pointer */
+static int (*ptr_marsio_option_set)(struct mr_instance * instance, marsio_opt_type_t opt_type, void * opt, size_t sz_opt);
+static void (*ptr_marsio_send_burst_flush)(struct mr_sendpath * sendpath, queue_id_t sid);
+static int (*ptr_marsio_init)(struct mr_instance * instance, const char * appsym);
+static struct mr_vdev * (*ptr_marsio_open_device)(struct mr_instance * instance,
+ const char * devsym, unsigned int nr_rxstream, unsigned int nr_txstream);
+static void (*ptr_marsio_close_device)(struct mr_vdev *vdev);
+static struct mr_sendpath * (*ptr_marsio_sendpath_create_by_vdev)(struct mr_vdev * dest_device);
+static void (*ptr_marsio_sendpath_destory)(struct mr_sendpath * sendpath);
+static struct mr_instance * (*ptr_marsio_create)(void);
+static int (*ptr_marsio_destory)(struct mr_instance *instance);
+static int (*ptr_marsio_thread_init)(struct mr_instance * instance);
+static int (*ptr_marsio_recv_burst)(struct mr_vdev * vdev, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs);
+int (*ptr_marsio_send_burst)(struct mr_sendpath * sendpath, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs);
+static int (*ptr_marsio_send_burst_with_options)(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[], int nr_mbufs, uint16_t options);
+void (*ptr_marsio_buff_free)(struct mr_instance * instance, marsio_buff_t *marsio_buff[],unsigned int nr_mbufs, int socket_id, int thread_id);
+int (*ptr_marsio_buff_malloc_global)(struct mr_instance * instance, marsio_buff_t *marsio_buff[], unsigned int nr_mbufs, int socket_id, int thread_id);
+char * (*ptr_marsio_buff_append)(marsio_buff_t *m, uint16_t len);
+void * (*ptr_marsio_buff_ctrlzone)(marsio_buff_t *m, uint8_t id);
+void (*ptr_marsio_buff_ctrlzone_set)(marsio_buff_t *m, uint8_t id, void* ptr_data, uint8_t size);
+void (*ptr_marsio_buff_set_rehash_index)(marsio_buff_t *m, uint32_t hash);
+char * (*ptr_marsio_buff_mtod)(marsio_buff_t *m);
+uint32_t (*ptr_marsio_buff_datalen)(marsio_buff_t *m);
+uint32_t (*ptr_marsio_buff_buflen)(marsio_buff_t *m);
+marsio_buff_t * (*ptr_marsio_buff_clone_with_options)(struct mr_instance * instance, marsio_buff_t * md, int socket_id, int thread_id, uint16_t options);
+int (*ptr_marsio_buff_get_metadata)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
+int (*ptr_marsio_buff_set_metadata)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data);
+int (*ptr_marsio_buff_unset_metadata)(marsio_buff_t *m, enum mr_buff_metadata_type type);
+marsio_buff_t *(*ptr_marsio_buff_malloc_smartoffload)(struct mr_vdev *vdev, const char * pkt, unsigned int pkt_len);
+
+int (*ptr_marsio_buff_get_sid_list)(marsio_buff_t * m, uint16_t * out_slist, uint8_t sz_out_slist);
+int (*ptr_marsio_buff_set_sid_list)(marsio_buff_t * m, uint16_t * slist, uint8_t sz_slist);
+int (*ptr_marsio_buff_append_sid_list)(marsio_buff_t * m, uint16_t * slist, uint8_t sz_slist);
+int (*ptr_marsio_buff_prepend_sid_list)(marsio_buff_t * m, uint16_t * slist, uint8_t sz_slist);
+
+void (*ptr_marsio_buff_set_ctrlbuf)(marsio_buff_t * m);
+
+
+static struct bpf_program MARSIO_BPF_FILTER[MAX_THREAD_NUM];
+static int g_marsio_have_bpf;
+
+struct __marsio_bpf_counter_t
+{
+ long count;
+} __attribute__((aligned(64))); /* for multi-thread, must 64byte alignment */
+struct __marsio_bpf_counter_t g_marsio_bpf_counter[MAX_THREAD_NUM];
+
+/************************ funcitons for dynamic link *************************/
+
+int marsio_dl_io_set_cap_level(int cap_level)
+{
+ g_marsio4_cap_level = cap_level;
+
+ return 0;
+}
+
+int marsio_dl_io_set_cap_mode(int cap_mode)
+{
+ (void)cap_mode;
+ return 0;
+}
+
+int marsio_dl_io_set_topology_mode(int topology_mode)
+{
+ switch(topology_mode){
+ case NET_CONN_PARA_NOSEND:
+ case NET_CONN_PARALLEL:
+ case NET_CONN_SERIAL_GDEV:
+ case NET_CONN_SERIAL_2CARD:
+ g_marsio4_topology_mode = topology_mode;
+ break;
+
+
+ default:
+ printf("\033[1;31;40m[Error]Invalid net_connection_mode!\033[0m\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int marsio_dl_io_set_capdev_parallel(const char *cap_dev)
+{
+ char *save_ptr, *tmp_cap_dev_name;
+ const char *delim = ", ";
+ char cfg_name_from_conf[1024];
+ char *single_device;
+
+ /* marsio4ģʽ�������������ж��, ����ԭ�е�pcapdevice����, �����ŷָ� */
+ if(NULL == cap_dev){
+ printf("\033[1;31;40m[Error]Invalid pcapdevice!\033[0m\n");
+ return -1;
+ }
+
+ /* marsioģʽ֧�ֶ�����, ���ŷָ�ģʽ */
+ strncpy(cfg_name_from_conf, sapp_global_val->config.packet_io.internal.interface.name, sizeof(cfg_name_from_conf));
+ tmp_cap_dev_name = cfg_name_from_conf;
+
+ while((single_device = strtok_r(tmp_cap_dev_name, delim, &save_ptr)) != NULL){
+ if(NULL == g_mr4_up_device_name){
+ g_mr4_up_device_name = (char **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, sizeof(void *) * (g_mr4_device_num + 1));
+ }else{
+ g_mr4_up_device_name = (char **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID, g_mr4_up_device_name, sizeof(void *) * (g_mr4_device_num + 1));
+ }
+
+ g_mr4_up_device_name[g_mr4_device_num] = sapp_strdup(single_device);
+
+ g_mr4_device_num++;
+ tmp_cap_dev_name = NULL;
+ }
+
+ return 0;
+}
+
+int marsio_dl_io_set_capdev_serial(const char *up_dev, const char *down_dev)
+{
+ char *save_ptr;
+ const char *delim = ", ";
+ char *tmp_cap_dev_name, *save_mem_ptr;
+ char *single_device;
+ int local_mr4_serial_device_num = 0;
+
+ /* marsio4ģʽ�������������ж��, ����ԭ�е�pcapdevice����, �����ŷָ� */
+ if(NULL == down_dev){
+ printf("\033[1;31;40m[Error]Invalid pcapdevice!\033[0m\n");
+ return -1;
+ }
+
+ tmp_cap_dev_name = sapp_strdup(down_dev);
+ save_mem_ptr = tmp_cap_dev_name;
+
+ while((single_device = strtok_r(tmp_cap_dev_name, delim, &save_ptr)) != NULL){
+ if(NULL == g_mr4_down_device_name){
+ g_mr4_down_device_name = (char **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,sizeof(void *) * (local_mr4_serial_device_num + 1));
+ }else{
+ g_mr4_down_device_name = (char **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,g_mr4_down_device_name, sizeof(void *) * (local_mr4_serial_device_num + 1));
+ }
+
+ g_mr4_down_device_name[local_mr4_serial_device_num] = sapp_strdup(single_device);
+
+ local_mr4_serial_device_num++;
+ tmp_cap_dev_name = NULL;
+ }
+
+ if(local_mr4_serial_device_num != g_mr4_device_num){
+ printf("\033[1;31;40m[Error]capture device up and down number is not match!\033[0m\n");
+ return -1;
+ }
+
+ SAPP_GLOBAL_FREE(save_mem_ptr);
+
+ return 0;
+}
+
+int marsio_dl_io_set_capture_filter(const char *filter_rule)
+{
+ memset(&g_marsio_bpf_counter, 0, sizeof(g_marsio_bpf_counter));
+ g_marsio_have_bpf=0;
+
+ if(strlen(filter_rule) == 0)return -1;
+ int i,j;
+
+ int pcap_link_type = DLT_EN10MB;
+ for (i = 0; i < (unsigned int)g_packet_io_thread_num; i++)
+ {
+ if (pcap_compile_nopcap(65535, pcap_link_type, &MARSIO_BPF_FILTER[i], filter_rule, 100, 0) < 0)
+ {
+ printf("Compile pcap filter '%s' error\n", filter_rule);
+ for(j = 0; j < (unsigned int )g_packet_io_thread_num; j++)
+ {
+ pcap_freecode(&MARSIO_BPF_FILTER[j]);
+ }
+ return -1;
+ }
+ }
+ g_marsio_have_bpf=1;
+ return 0;
+}
+
+int marsio_dl_io_set_cap_buf_queue(int queue_num_max)
+{
+ (void)queue_num_max; /* �������� */
+ return 0;
+}
+
+int marsio_dl_io_set_work_thread_num(int thread_num_max)
+{
+ g_marsio4_work_thread_num = thread_num_max;
+ return 0;
+}
+
+
+long marsio_dl_io_get_app_drop_num(int thread_num)
+{
+ /* pagģʽ�鿴������ר�ù���, ����Ŀǰ���ṩ�˹��� */
+ (void)thread_num;
+ return 0;
+}
+
+long marsio_dl_io_get_lib_drop_num(void)
+{
+ long total_drop = 0;
+ int i;
+ for(i = 0; i < g_marsio4_work_thread_num; i++)
+ {
+ total_drop +=g_marsio_bpf_counter[i].count;
+ }
+ return total_drop;
+}
+
+
+unsigned char *marsio_dl_io_get_sendbuf(void *phandle, int thread_seq)
+{
+
+ marsio4_io_handle *mr4_handle = (marsio4_io_handle *)phandle;
+ mr4_handle->send_mbuf_mtod_ptr = malloc(SENDPACKET_PACKET_SIZE);
+ return (unsigned char *)mr4_handle->send_mbuf_mtod_ptr;
+}
+
+void marsio_dl_io_free_sendbuf(void *phandle, int thread_seq)
+{
+ marsio4_io_handle *mr4_handle = (marsio4_io_handle *)phandle;
+ free(mr4_handle->send_mbuf_mtod_ptr);
+ return;
+}
+
+/* 2020-10-30 lijia add, in/forward/inject����tcpdump_mesa, ����debug. */
+static void marsio_pkt_dump(int thread_seq, const marsio_buff_t *send_mbuf, enum _pkt_classify class)
+{
+ raw_pkt_t to_tcpdump_mesa;
+
+ if(0 == G_PKT_DUMP_SW){
+ return;
+ }
+
+ to_tcpdump_mesa.low_layer_type = ADDR_TYPE_MAC;
+ to_tcpdump_mesa.raw_pkt_data = ptr_marsio_buff_mtod((marsio_buff_t *)send_mbuf);
+ to_tcpdump_mesa.raw_pkt_len = ptr_marsio_buff_buflen((marsio_buff_t *)send_mbuf);
+ cycle_pkt_dump_by_classify(thread_seq, &to_tcpdump_mesa, class);
+
+}
+
+static void marsio_update_trace_id(const raw_pkt_t *raw_pkt, void *send_pkt_io_reference)
+{
+ if(ptr_marsio_buff_set_metadata!=NULL && raw_pkt->stream_trace_id>0)
+ {
+ ptr_marsio_buff_set_metadata((marsio_buff_t *)send_pkt_io_reference, MR_BUFF_SESSION_ID, (void *)&(raw_pkt->stream_trace_id), sizeof(unsigned long));
+ }
+}
+
+static void marsio_update_sid_list(const raw_pkt_t *raw_pkt, void *send_pkt_io_reference)
+{
+ if(raw_pkt->append_list && ptr_marsio_buff_append_sid_list!= NULL)
+ {
+ ptr_marsio_buff_append_sid_list((marsio_buff_t *)send_pkt_io_reference, raw_pkt->append_list->sid_list, raw_pkt->append_list->sz_sidlist);
+ }
+ if(raw_pkt->prepend_list && ptr_marsio_buff_prepend_sid_list != NULL)
+ {
+ ptr_marsio_buff_prepend_sid_list((marsio_buff_t *)send_pkt_io_reference, raw_pkt->prepend_list->sid_list, raw_pkt->prepend_list->sz_sidlist);
+ }
+ return;
+}
+
+static void marsio_update_payload_offset(unsigned short offset, void *send_pkt_io_reference)
+{
+ if(ptr_marsio_buff_set_metadata!=NULL)
+ {
+ ptr_marsio_buff_set_metadata((marsio_buff_t *)send_pkt_io_reference, MR_BUFF_PAYLOAD_OFFSET, (void *)&(offset), sizeof(unsigned short));
+ }
+}
+
+int marsio_dl_io_raw_pkt_send(void *phandle, unsigned char *data,int datalen, void *arg,
+ int thread_seq, unsigned char route_dir, const raw_pkt_t *raw_pkt)
+{
+ int ret;
+ marsio_buff_t *send_mbuf[1];
+ char *real_buf;
+ struct mr_tunnat_ctrlzone mr_ctrlzone = {};
+ uint16_t send_option = 0;
+
+ ret = ptr_marsio_buff_malloc_global(sapp_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_seq);
+ if((ret < 0) || (NULL == send_mbuf[0])){
+ return -1;
+ }
+
+
+ /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
+ real_buf = ptr_marsio_buff_append(send_mbuf[0], datalen);
+ if(NULL == real_buf){
+ ptr_marsio_buff_free(sapp_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_seq);
+ return -1;
+ }
+
+ memcpy(real_buf, data, datalen);
+
+ if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){
+ mr_ctrlzone.action = TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
+ send_option = MARSIO_SEND_OPT_FAST|MARSIO_SEND_OPT_REHASH;
+ }else{
+ /* v4.2֮��, sapp����mrtunnat֧��, ֱ�ӷ���ԭʼ��, ����Ҫ������װ�ײ���·��Ϣ */
+ mr_ctrlzone.action = TUNNAT_CZ_ACTION_ENCAP_NO_SESSION;
+ send_option = MARSIO_SEND_OPT_FAST;
+ }
+
+ if(raw_pkt){
+ packet_io_hook_sendto(raw_pkt, route_dir, real_buf, (void *)send_mbuf[0]);
+ }
+ else
+ {
+ if(raw_pkt->append_list)
+ {
+ ptr_marsio_buff_set_sid_list(send_mbuf[0], raw_pkt->append_list->sid_list, raw_pkt->append_list->sz_sidlist);
+ }
+
+ if(raw_pkt->prepend_list)
+ {
+ ptr_marsio_buff_set_sid_list(send_mbuf[0], raw_pkt->prepend_list->sid_list, raw_pkt->prepend_list->sz_sidlist);
+ }
+
+ marsio_update_trace_id(raw_pkt, (void *)send_mbuf[0]);
+ }
+
+ ptr_marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
+
+ if(ptr_marsio_buff_set_ctrlbuf!=NULL && raw_pkt->is_send_ctrl_pkt==1)
+ {
+ ptr_marsio_buff_set_ctrlbuf(send_mbuf[0]);
+ unsigned short offset=(unsigned short)(ptr_marsio_buff_datalen(send_mbuf[0]) - raw_pkt->payload_len);
+ marsio_update_payload_offset(offset, (void *)send_mbuf[0]);
+ }
+
+ ret = ptr_marsio_send_burst_with_options((struct mr_sendpath *)arg, thread_seq, send_mbuf, 1, send_option);
+ if(ret < 0){
+ return -1;
+ }
+ marsio_pkt_dump(thread_seq, send_mbuf[0], PKT_CLASSIFY_INJECT);
+ return datalen;
+}
+
+int marsio_dl_io_low_level_send(void *phandle, UINT8 *data,int datalen,
+ int eth_carry_layer_addr_type, int dir,int thread_num,const raw_pkt_t *raw_pkt)
+{
+ int ret;
+ struct mesa_ethernet_hdr *ehdr = (struct mesa_ethernet_hdr *)data;
+ //��˫����͸��ģʽ(transparent)��, ����dirѡ��up or down device����.
+ if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
+ assert((dir >= 0) && (dir <= 1));
+ ret = marsio_dl_io_raw_pkt_send(phandle, data, datalen, g_packet_device_alias[dir].dl_io_param, thread_num, dir, raw_pkt);
+ }else{
+ /* ��֧�ֶ������, ԭʼ�������յ��ʹ��ij�ȥ */
+ ret = marsio_dl_io_raw_pkt_send(phandle, data, datalen, g_mr4_sendpath_up_set[raw_pkt->device_index], thread_num,dir, raw_pkt);
+ }
+
+ return ret;
+}
+
+int marsio_dl_io_smart_offload(int device_index, unsigned char *pkt_ptr, int pkt_len, unsigned char dir, int thread_num)
+{
+ if(ptr_marsio_buff_malloc_smartoffload!=NULL && ptr_marsio_send_burst_with_options!=NULL)
+ {
+ /* for all vxlan pkts, create an offload request */
+ marsio_buff_t * offload_request_buf = ptr_marsio_buff_malloc_smartoffload(g_mr4_dev_up_handle_set[device_index], (const char *)pkt_ptr, pkt_len);
+ if(offload_request_buf==NULL)
+ {
+ return 0;
+ }
+ /* inject the offload request */
+ ptr_marsio_send_burst_with_options(g_mr4_sendpath_up_set[device_index], thread_num, &offload_request_buf, 1, MARSIO_SEND_OPT_CTRL);
+ return 1;
+ }
+ return 0;
+}
+
+static int marsio4_pkt_forward(int tid, struct mr_sendpath * sendpath, marsio_buff_t * mbufs);
+
+int marsio_dl_io_forward_rawpkt(const raw_pkt_t *raw_pkt, int thread_seq)
+{
+ if(raw_pkt == NULL && (thread_seq < 0 || thread_seq > get_thread_count()))
+ return -1;
+ int ret = 0;
+ if(raw_pkt->io_lib_pkt_reference != NULL)
+ {
+ marsio_update_trace_id(raw_pkt, (void *)raw_pkt->io_lib_pkt_reference);
+ marsio_update_sid_list(raw_pkt, (void *)raw_pkt->io_lib_pkt_reference);
+ ret = marsio4_pkt_forward(thread_seq, g_mr4_sendpath_up_set[raw_pkt->device_index], (marsio_buff_t *)raw_pkt->io_lib_pkt_reference);
+ }
+ return ret;
+}
+
+void marsio_dl_io_free_rawpkt(const raw_pkt_t *raw_pkt, int thread_seq)
+{
+ if(raw_pkt == NULL && (thread_seq < 0 || thread_seq > get_thread_count()))
+ return;
+ ptr_marsio_buff_free(sapp_marsio4_instance, (marsio_buff_t **)&raw_pkt->io_lib_pkt_reference, 1, MARSIO_SOCKET_ID_ANY, thread_seq);
+ return;
+}
+
+
+struct rawpkt_metadata *marsio_dl_io_get1_rawpkt_meta(const raw_pkt_t *raw_pkt, int thread_seq)
+{
+ struct rawpkt_metadata *meta = NULL;
+ int ret = 0;
+ if(raw_pkt->io_lib_pkt_reference != NULL)
+ {
+ if (ptr_marsio_buff_get_sid_list != NULL || ptr_marsio_buff_get_metadata != NULL)
+ {
+ meta = (struct rawpkt_metadata *)sapp_mem_calloc(SAPP_MEM_DYN_SID_LIST, thread_seq,sizeof(struct rawpkt_metadata));
+ if (ptr_marsio_buff_get_metadata)
+ {
+ ret = ptr_marsio_buff_get_metadata((marsio_buff_t *)raw_pkt->io_lib_pkt_reference,
+ MR_BUFF_ROUTE_CTX, meta->data, MAX_METADATA_LEN);
+ if (ret <= 0)
+ {
+ sapp_mem_free(SAPP_MEM_DYN_SID_LIST, thread_seq,meta);
+ return NULL;
+ }
+ else
+ {
+ meta->sz_data = ret;
+ }
+ }
+ if (ptr_marsio_buff_get_sid_list)
+ {
+ ret = ptr_marsio_buff_get_sid_list((marsio_buff_t *)raw_pkt->io_lib_pkt_reference,
+ meta->raw_sid_list.sid_list, MAX_SID_NUM);
+ if (ret <= 0)
+ {
+ meta->raw_sid_list.sz_sidlist = 0;
+ }
+ else
+ {
+ meta->raw_sid_list.sz_sidlist = ret;
+ }
+ }
+ if (meta->sz_data == 0 && meta->raw_sid_list.sz_sidlist == 0)
+ {
+ sapp_mem_free(SAPP_MEM_DYN_SID_LIST, thread_seq,meta);
+ meta = NULL;
+ }
+ }
+ }
+
+ return meta;
+}
+
+
+
+void marsio_dl_io_set_rawpkt_meta(const raw_pkt_t *raw_pkt, void *send_pkt_io_reference, unsigned char route_dir)
+{
+ if(raw_pkt->meta[0]== NULL && (raw_pkt->meta[1]== NULL))
+ {
+ return ;
+ }
+
+ struct rawpkt_metadata *snd_meta = NULL;
+ if(raw_pkt->meta[route_dir]!=NULL)
+ {
+ snd_meta=raw_pkt->meta[route_dir];
+ }
+ else // failover
+ {
+ snd_meta=raw_pkt->meta[route_dir^1];
+ }
+ if(ptr_marsio_buff_set_metadata)
+ {
+ ptr_marsio_buff_set_metadata((marsio_buff_t *)send_pkt_io_reference, MR_BUFF_ROUTE_CTX, (void *)snd_meta->data, snd_meta->sz_data);
+ }
+
+ marsio_update_trace_id(raw_pkt, send_pkt_io_reference);
+
+ if(ptr_marsio_buff_set_sid_list==NULL)
+ {
+ return ;
+ }
+
+ if(raw_pkt->is_send_ctrl_pkt==0)
+ {
+ ptr_marsio_buff_set_sid_list((marsio_buff_t *)send_pkt_io_reference, snd_meta->raw_sid_list.sid_list, snd_meta->raw_sid_list.sz_sidlist);
+ marsio_update_sid_list(raw_pkt, send_pkt_io_reference);
+ return ;
+ }
+
+ if(raw_pkt->append_list)
+ {
+ ptr_marsio_buff_set_sid_list((marsio_buff_t *)send_pkt_io_reference, raw_pkt->append_list->sid_list, raw_pkt->append_list->sz_sidlist);
+ }
+
+ if(raw_pkt->prepend_list)
+ {
+ ptr_marsio_buff_set_sid_list((marsio_buff_t *)send_pkt_io_reference, raw_pkt->prepend_list->sid_list, raw_pkt->prepend_list->sz_sidlist);
+ }
+
+ return;
+}
+
+void marsio_dl_io_free_rawpkt_meta(struct rawpkt_metadata * meta, int thread_seq)
+{
+ if(meta != NULL)
+ {
+ sapp_mem_free(SAPP_MEM_DYN_SID_LIST, thread_seq,meta);
+ meta=NULL;
+ }
+ return;
+}
+
+
+void *marsio_dl_io_get_send_handle(int thread_seq)
+{
+ return (void *)&g_mario4_io_handle[thread_seq];
+}
+
+
+int marsio_dl_io_get_version(void)
+{
+ return g_marsio4_version_VERSION;
+}
+
+int marsio_dl_io_register_cb(PACKET_IO_CB_T fun)
+{
+ g_marsio4_work_fun = fun;
+ return 0;
+}
+
+int marsio_dl_io_send_only_thread_init(void)
+{
+ if(sapp_global_val->config.cpu.bind_mask_array_num > 0){
+ ptr_marsio_thread_init(sapp_marsio4_instance);
+ }
+
+ return 0;
+}
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+static int tmp_vdevice_num;
+static char **tmp_vdevice_name; /* �����豸�����б�, ��pag.conf�еIJ����豸, ��������Ӧ��ģʽ��ע */
+static struct mr_sendpath **tmp_vdevice_sendpath;
+void * marsio_dl_io_device_alias(unsigned int target_id, char *device_args)
+{
+ int i;
+ int len1, len2;
+
+ len1 = strlen(device_args);
+
+ for(i = 0; i < g_mr4_device_num; i++){
+ len2 = strlen(g_mr4_up_device_name[i]);
+ /* ʹ������ַ��Ƚ�, ��ֹ"eth12", "eth1"�Ƚϵ���ȵ�BUG */
+ if(strncasecmp(device_args, g_mr4_up_device_name[i], MAX(len1, len2)) == 0){
+ return (void *)g_mr4_sendpath_up_set[i];
+ }
+ }
+
+ if(NULL != g_mr4_down_device_name){
+ for(i = 0; i < g_mr4_device_num; i++){
+ len2 = strlen(g_mr4_down_device_name[i]);
+ /* ʹ������ַ��Ƚ�, ��ֹ"eth12", "eth1"�Ƚϵ���ȵ�BUG */
+ if(strncasecmp(device_args, g_mr4_down_device_name[i], MAX(len1, len2)) == 0){
+ return (void *)g_mr4_sendpath_down_set[i];
+ }
+ }
+ }
+
+ /* �˿�δ��pag.conf��ע��, �����������豸����, �ֳ��򿪷��;�� */
+ struct mr_vdev *t_vdev;
+ struct mr_sendpath *t_sendpath;
+
+ for(i = 0; i < tmp_vdevice_num; i++){
+ len2 = strlen(tmp_vdevice_name[i]);
+ /* ʹ������ַ��Ƚ�, ��ֹ"eth12", "eth1"�Ƚϵ���ȵ�BUG */
+ if(strncasecmp(device_args, tmp_vdevice_name[i], MAX(len1, len2)) == 0){
+ return (void *)tmp_vdevice_sendpath[i];
+ }
+ }
+ /* û�ҵ�, ���豸, ���洢���;�� */
+ if(0 == tmp_vdevice_num){
+ tmp_vdevice_name = (char **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,sizeof(void *));
+ tmp_vdevice_sendpath = (struct mr_sendpath **)sapp_mem_calloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,sizeof(void *));
+ }else{
+ tmp_vdevice_name = (char **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,tmp_vdevice_name, sizeof(void *) * (tmp_vdevice_num + 1));
+ tmp_vdevice_sendpath = (struct mr_sendpath **)sapp_mem_realloc(SAPP_MEM_FIX_GLOBAL_VAL, MEM_STAT_GLOBAL_THREAD_ID,tmp_vdevice_sendpath, sizeof(void *) * (tmp_vdevice_num + 1));
+ }
+ tmp_vdevice_name[tmp_vdevice_num] = sapp_strdup(device_args);
+
+ t_vdev = ptr_marsio_open_device(sapp_marsio4_instance, device_args,
+ 0,
+ g_marsio4_work_thread_num);
+ if(NULL == t_vdev){
+ printf("\033[41m[Error]Can't open device '%s'!\033[0m\n", device_args);
+ return NULL;
+ }
+ t_sendpath = ptr_marsio_sendpath_create_by_vdev(t_vdev);
+ tmp_vdevice_sendpath[tmp_vdevice_num] = t_sendpath;
+ tmp_vdevice_num++; /* �����¼����� */
+
+ return t_sendpath;
+}
+
+/************************ funcitons for dynamic link *************************/
+
+/*
+ ����һ�������������˶��ٸ�bit��1��.
+*/
+static inline int calc_integer_bit_num(unsigned long long num)
+{
+ int i = 0;
+ int bit_num = 0;
+
+ for(i = 0; i < (int)sizeof(long long) * 8; i++){
+ if(num & 1){
+ bit_num++;
+ }
+ num = num >> 1;
+ if(0 == num){ /* num�Ѿ���0��, ��û��Ҫ���жϺ���bitλ�� */
+ break;
+ }
+ }
+
+ return bit_num;
+}
+
+static int marsio4_pkt_forward_for_gdev_mode(int tid, struct mr_sendpath * sendpath, marsio_buff_t * mbuf)
+{
+ char tmp_mac[6];
+ struct mesa_ethernet_hdr *eth_hdr = (struct mesa_ethernet_hdr *)ptr_marsio_buff_mtod(mbuf);
+
+ /* ����Դ��Ŀ��MAC��ַ, �ٰ�ԭʼ����ע��GDEV */
+ memcpy(tmp_mac, eth_hdr->ether_shost, 6);
+ memcpy(eth_hdr->ether_shost, eth_hdr->ether_dhost, 6);
+ memcpy(eth_hdr->ether_dhost, tmp_mac, 6);
+
+ return ptr_marsio_send_burst(sendpath, tid, &mbuf, 1);
+}
+
+static int marsio4_pkt_forward(int tid, struct mr_sendpath * sendpath, marsio_buff_t * mbufs)
+{
+ int ret = 0;
+ struct mr_tunnat_ctrlzone *ctrl_zone;
+
+ ctrl_zone = (struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone(mbufs, 0);
+
+ /* ������ȡ, ���������������, vxlan��������װģʽ����ʹ��, Ҫ��ÿ��mbuf�жϵײ��װģʽ */
+ if((ctrl_zone->action & TUNNAT_CZ_ACTION_FORWARD)
+ || (0 != sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support)){
+ /* 20201010 lijia modify, ����overlay��mrtunnat��ģʽ��, ctrl_zone�ǿ�, Ĭ�϶���ע */
+ /* 20190409 lijia modify, tunnel mode, ��������װ�İ����ܻ�ע */
+ /* vxlan��װ�ڲ�����ת���������κβ���, ֱ�ӵ���marsio_send_burst, ��marsio�������� */
+ ctrl_zone->action = TUNNAT_CZ_ACTION_FORWARD;
+ ptr_marsio_buff_ctrlzone_set(mbufs, 0, ctrl_zone, sizeof(struct mr_tunnat_ctrlzone));
+ ret = ptr_marsio_send_burst(sendpath, tid, &mbufs, 1);
+
+ marsio_pkt_dump(tid, mbufs, PKT_CLASSIFY_FORWARD);
+ }
+ else
+ {
+ ret = -1;
+ }
+ return ret;
+}
+
+
+static inline int marsio4_pkt_hand(int tid, marsio_buff_t *rx_buff, raw_pkt_t *raw_pkt, unsigned char dir)
+{
+ int ret;
+
+ raw_pkt->__lib_raw_pkt_data = ptr_marsio_buff_mtod(rx_buff);
+ raw_pkt->raw_pkt_data = raw_pkt->__lib_raw_pkt_data;
+ raw_pkt->__lib_raw_pkt_len = ptr_marsio_buff_datalen(rx_buff);
+ raw_pkt->raw_pkt_len = raw_pkt->__lib_raw_pkt_len;
+ raw_pkt->io_lib_pkt_reference = rx_buff;
+ /* ˫��ģʽdir��������internal, external����,
+ inlineģʽ��ʱ��dir������, ���ջ��� packet_io_hook_input_vxlan() ,ͨ��vxlan header����routedir .
+ */
+ raw_pkt->route_dir = dir;
+
+ if(unlikely(g_marsio_have_bpf == 1))
+ {
+ if (0 == bpf_filter(MARSIO_BPF_FILTER[tid].bf_insns,
+ (const unsigned char *)raw_pkt->raw_pkt_data,
+ raw_pkt->raw_pkt_len, raw_pkt->raw_pkt_len))
+ {
+ g_marsio_bpf_counter[tid].count++;
+ return DROP;
+ }
+ }
+
+ if(0 == sapp_global_val->config.packet_io.packet_io_tunnel.l2_l3_tunnel_support){
+ struct mr_tunnat_ctrlzone *mr_ctrlzone = (struct mr_tunnat_ctrlzone *)ptr_marsio_buff_ctrlzone(rx_buff, 0); /* index */
+ raw_pkt->is_overlay_pkt = mr_ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD;
+ }else{
+ if(OVERLAY_MODE_NF == sapp_global_val->config.packet_io.packet_io_tunnel.overlay_mode_bin)
+ {
+ raw_pkt->is_overlay_pkt = 1;
+ }
+ else
+ {
+ raw_pkt->is_overlay_pkt = 0; /* ��mrtunnatʱ, ���յ�������ȷ��, ��packet_io_hook�����Ƿ���overlay�İ� */
+ }
+ }
+
+ /* clear pkt status */
+ raw_pkt->diagnose_error_to_dump = 0;
+ raw_pkt->vlan_flipping_couple[0] = 0;
+ raw_pkt->vlan_flipping_couple[1] = 0;
+ raw_pkt->overlay_layer_bytes = 0;
+ raw_pkt->drop_current_pkt_flag = 0;
+ raw_pkt->d_pkt = NULL;
+
+ //ret = (*g_marsio4_work_fun)((const raw_pkt_t *)raw_pkt, mr_ctrlzone->route_dir, tid);
+ ret = (*g_marsio4_work_fun)((const raw_pkt_t *)raw_pkt, dir, tid);
+
+ return ret;
+}
+
+static int marsio4_process_packet(int tid, raw_pkt_t *raw_pkt)
+{
+ int i,j,k, pkt_num = 0;
+ marsio_buff_t * rx_buff[MARSIO_BURST_PKT_MAX]; /* ����豸֮���Ǵ��л�ȡ, ̫�������ܵ�, ̫���������ʱ�� */
+ int rcv_res, hand_res;
+
+ if((__NET_CONN_PARALLEL & g_marsio4_topology_mode) != 0){
+ for(i = 0; i < g_mr4_device_num; i++){
+ rcv_res = ptr_marsio_recv_burst(g_mr4_dev_up_handle_set[i], tid, rx_buff, marsio4_burst_process_pkt_num);
+ if(rcv_res > 0){
+ raw_pkt->device_index = i;
+ __builtin_prefetch(ptr_marsio_buff_mtod(rx_buff[0]));
+
+ for(j = 0, k = 1; j < rcv_res; j++, k++){
+ if(k < rcv_res) {
+ __builtin_prefetch(ptr_marsio_buff_mtod(rx_buff[k]));
+ }
+
+ marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_UP); /* ����ģʽ�����ķ���ֵ */
+ }
+ pkt_num += rcv_res;
+ ptr_marsio_buff_free(sapp_marsio4_instance, rx_buff, rcv_res, MARSIO_SOCKET_ID_ANY, tid); /* �������漰����, ������ҵ����������free */
+ }
+ }
+ }else if(NET_CONN_SERIAL_GDEV == g_marsio4_topology_mode){
+ for(i = 0; i < g_mr4_device_num; i++){
+ rcv_res = ptr_marsio_recv_burst(g_mr4_dev_up_handle_set[i], tid, rx_buff, 16);
+ if(rcv_res > 0){
+ for(j = 0; j < rcv_res; j++){
+ raw_pkt->device_index = i;
+ hand_res = marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_UP); /* ��marsio4_pkt_hand()����dir */
+ if ((g_marsio4_topology_mode & __NET_CONN_SERIAL) && (PASS == hand_res))
+ {
+ /* NOTE:
+ MARSIO����ģʽ������, �����������հ�, ��Ҫͨ������������ע��,
+ */
+ marsio_update_sid_list(raw_pkt, (void *)rx_buff[j]);
+ marsio_update_trace_id(raw_pkt, (void *)rx_buff[j]);
+ int ret = marsio4_pkt_forward(tid, g_mr4_sendpath_up_set[i], rx_buff[j]);
+ if (ret < 0)
+ {
+ ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
+ }
+ }
+ else if (hand_res == DROP)
+ {
+ /* ����ģʽ��ֻ�ܵ���free, �п���batch�յ�N������, ij������Ҫ��ע, ij��������Ҫ */
+ ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
+ }
+ else
+ ;
+ }
+ pkt_num += rcv_res;
+ }
+ }
+ }else if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
+ for(i = 0; i < g_mr4_device_num; i++){
+ rcv_res = ptr_marsio_recv_burst(g_mr4_dev_up_handle_set[i], tid, rx_buff, marsio4_burst_process_pkt_num);
+ if(rcv_res > 0){
+ for(j = 0; j < rcv_res; j++){
+ hand_res = marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_UP);
+ if((g_marsio4_topology_mode & __NET_CONN_SERIAL) && (PASS == hand_res)){
+ //marsio4_pkt_forward(tid, rx_buff[j]);
+ ptr_marsio_send_burst(g_mr4_sendpath_down_set[i], tid, &rx_buff[j], 1);
+ }else{
+ /* ����ģʽ�µ���free, �п�����Ҫ��ע/���� */
+ ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
+ }
+ }
+ pkt_num += rcv_res;
+ }
+ rcv_res = ptr_marsio_recv_burst(g_mr4_dev_down_handle_set[i], tid, rx_buff, marsio4_burst_process_pkt_num);
+ if(rcv_res > 0){
+ for(j = 0; j < rcv_res; j++){
+ hand_res = marsio4_pkt_hand(tid, rx_buff[j], raw_pkt, DIR_ROUTE_DOWN);
+ if((g_marsio4_topology_mode & __NET_CONN_SERIAL) && (PASS == hand_res)){
+ //marsio4_pkt_forward(tid, rx_buff[j]);
+ ptr_marsio_send_burst(g_mr4_sendpath_up_set[i], tid, &rx_buff[j], 1);
+ }else{
+ /* ����ģʽ�µ���free, �п�����Ҫ��ע/���� */
+ ptr_marsio_buff_free(sapp_marsio4_instance, &rx_buff[j], 1, MARSIO_SOCKET_ID_ANY, tid);
+ }
+ }
+ pkt_num += rcv_res;
+ }
+ }
+ }
+
+ return pkt_num;
+}
+
+static int marsio4_sleep_time_table[100] =
+{
+ 5, 5, 5, 5, 5, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+
+static inline void marsio4_sleep(int tot_call_times, int rcv_pkt_times)
+{
+ float work_percent = ((float)rcv_pkt_times/(float)tot_call_times) * 100.0;
+
+ if((work_percent < 90.0) && (marsio4_sleep_time_table[(int)work_percent] > 0)){
+ sapp_usleep(marsio4_sleep_time_table[(int)work_percent]);
+ }
+}
+
+/* ������ģʽ��, marsio�����л���, ���°�����ʱ��Ҫ����ˢ�¶����е����� */
+static inline void marsio4_flush_queue_buf(int tid)
+{
+ int i;
+
+ if(NULL == ptr_marsio_send_burst_flush){
+ return;
+ }
+
+ for(i = 0; i < g_mr4_device_num; i++){
+ ptr_marsio_send_burst_flush(g_mr4_sendpath_up_set[i], tid);
+
+ if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
+ ptr_marsio_send_burst_flush(g_mr4_sendpath_down_set[i], tid);
+ }
+ }
+}
+
+static void *marsio4_worker(void *arg)
+{
+ int tseq = *((int *)arg);
+ raw_pkt_t raw_pkt;
+ int total_call_times = 0, rcv_pkt_tims = 0, polling_work_times = 0;
+
+ char thread_name[32] = "";
+ sprintf(thread_name, "sapp_marsio_%d", tseq);
+ prctl(PR_SET_NAME, thread_name);
+
+ if(sapp_global_val->config.cpu.bind_mask_array_num > 0){
+ ptr_marsio_thread_init(sapp_marsio4_instance);
+ sapp_global_val->individual_fixed.cpu_bind_core_id_per_thread[tseq] = get_current_thread_cpu_affinity_id();
+ }
+ sapp_global_val->individual_fixed.thread_tid[tseq] = syscall(SYS_gettid);
+
+ sapp_runtime_log(RLOG_LV_FATAL, "pid:%d, thread_index:%d, TID(LWP):%ld, PSR:%d",
+ getpid(), tseq,
+ sapp_global_val->individual_fixed.thread_tid[tseq],
+ sapp_global_val->individual_fixed.cpu_bind_core_id_per_thread[tseq]);
+
+ memset(&raw_pkt, 0, sizeof(raw_pkt_t));
+
+ /* �̶�����IJ���Ԥ������ */
+ raw_pkt.low_layer_type = (enum addr_type_t)g_marsio4_cap_level;
+ raw_pkt.magic_num = RAW_PKT_MAGIC_NUM;
+ raw_pkt.offset_to_raw_pkt_hdr = 0;
+
+ while(SAPP_STATE_PROCESSING != sapp_get_current_state()){
+ sapp_usleep(1000);
+ }
+
+ /* for perf optimize
+ Ƶ������stream_process_polling()�Ⱥ���, �˴����ں����ⲿ�ж�һ���Ƿ���Ҫ����.
+ */
+ int polling_enabled = sapp_global_val->config.packet_io.polling_enabled;
+ int infinite_loop_enabled = sapp_global_val->config.packet_io.infinite_loop_enabled;
+ while(SAPP_STATE_PROCESSING == sapp_global_val->individual_volatile->current_state){
+ if(marsio4_process_packet(tseq, &raw_pkt) > 0){
+ rcv_pkt_tims++;
+ }else{
+ marsio4_flush_queue_buf(tseq);
+ /* �ް�ʱҪ����polling�ӿ� */
+ if(polling_enabled && ((stream_process_polling(tseq) & POLLING_STATE_WORK) != 0)){
+ polling_work_times++;
+ }
+ if(polling_enabled && (polling_stream_timeout(tseq) & POLLING_STATE_WORK)){
+ polling_work_times++;
+ }
+ }
+
+ sapp_global_val->mthread_volatile[tseq]->sys_stat.count[SAPP_STAT_FETCH_PKT]++;
+ total_call_times++;
+
+ if((rcv_pkt_tims % sapp_global_val->config.packet_io.polling_priority) == 0){
+ /* ��������޴�, һֱ�а�ʱ, ÿ��polling_priority����ҲҪ����polling�ӿ� */
+ if(polling_enabled && ((stream_process_polling(tseq) & POLLING_STATE_WORK) != 0)){
+ polling_work_times++;
+ }
+ total_call_times++;
+ }
+
+ if(total_call_times >= 100){
+ if(likely(infinite_loop_enabled == 0))
+ {
+ marsio4_sleep(total_call_times, rcv_pkt_tims + polling_work_times);
+ }
+ total_call_times = 0;
+ rcv_pkt_tims = 0;
+ polling_work_times = 0;
+ }
+ }
+ return NULL;
+}
+
+static void fake_marsio_buff_set_rehash_index(marsio_buff_t *m, uint32_t hash)
+{
+ return ;
+}
+
+static int marsio_dl_get_function_entry(void)
+{
+ marsio_so_handle = dlopen(ABBR_MARSIO_LIBRARY_FILE, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
+ if(NULL == marsio_so_handle){
+ printf("\033[1;31;40m[Error]dlopen '%s' failed, %s\033[0m\n", ABBR_MARSIO_LIBRARY_FILE, dlerror());
+ return -1;
+ }
+
+ ptr_marsio_option_set = (int (*)(struct mr_instance * instance, marsio_opt_type_t opt_type, void * opt, size_t sz_opt))dlsym(marsio_so_handle, "marsio_option_set");
+ if(NULL == ptr_marsio_option_set){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_option_set", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_create = (struct mr_instance * (*)(void))dlsym(marsio_so_handle, "marsio_create");
+ if(NULL == ptr_marsio_create){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_create", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_close_device = (void (*)(struct mr_vdev *vdev))dlsym(marsio_so_handle, "marsio_close_device");
+ if(NULL == ptr_marsio_close_device){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_close_device", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_init = (int (*)(struct mr_instance * instance, const char * appsym))dlsym(marsio_so_handle, "marsio_init");
+ if(NULL == ptr_marsio_init){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_init", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_open_device = (struct mr_vdev * (*)(struct mr_instance * instance, const char * devsym, unsigned int nr_rxstream, unsigned int nr_txstream))dlsym(marsio_so_handle, "marsio_open_device");
+ if(NULL == ptr_marsio_open_device){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_open_device", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_sendpath_create_by_vdev = (struct mr_sendpath * (*)(struct mr_vdev * dest_device))dlsym(marsio_so_handle, "marsio_sendpath_create_by_vdev");
+ if(NULL == ptr_marsio_sendpath_create_by_vdev){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_sendpath_create_by_vdev", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_sendpath_destory = (void (*)(struct mr_sendpath * sendpath))dlsym(marsio_so_handle, "marsio_sendpath_destory");
+ if(NULL == ptr_marsio_sendpath_create_by_vdev){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_sendpath_destory", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_thread_init = (int (*)(struct mr_instance * instance))dlsym(marsio_so_handle, "marsio_thread_init");
+ if(NULL == ptr_marsio_thread_init){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_thread_init", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_recv_burst = (int (*)(struct mr_vdev * vdev, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs))dlsym(marsio_so_handle, "marsio_recv_burst");
+ if(NULL == ptr_marsio_recv_burst){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_recv_burst", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_send_burst = (int (*)(struct mr_sendpath * sendpath, queue_id_t qid, marsio_buff_t * mbufs[], int nr_mbufs))dlsym(marsio_so_handle, "marsio_send_burst");
+ if(NULL == ptr_marsio_send_burst){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_send_burst", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_send_burst_with_options = (int (*)(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[], int nr_mbufs, uint16_t options))dlsym(marsio_so_handle, "marsio_send_burst_with_options");
+ if(NULL == ptr_marsio_send_burst_with_options){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_send_burst_with_options", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_free = (void (*)(struct mr_instance * instance, marsio_buff_t *marsio_buff[],unsigned int nr_mbufs, int socket_id, int thread_id))dlsym(marsio_so_handle, "marsio_buff_free");
+ if(NULL == ptr_marsio_buff_free){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_free", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_malloc_global = (int (*)(struct mr_instance * instance, marsio_buff_t *marsio_buff[], unsigned int nr_mbufs, int socket_id, int thread_id))dlsym(marsio_so_handle, "marsio_buff_malloc_global");
+ if(NULL == ptr_marsio_buff_malloc_global){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_malloc_global", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_append = (char * (*)(marsio_buff_t *m, uint16_t len))dlsym(marsio_so_handle, "marsio_buff_append");
+ if(NULL == ptr_marsio_buff_append){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_append", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_ctrlzone = (void * (*)(marsio_buff_t *m, uint8_t id))dlsym(marsio_so_handle, "marsio_buff_ctrlzone");
+ if(NULL == ptr_marsio_buff_ctrlzone){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_ctrlzone", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_ctrlzone_set = (void (*)(marsio_buff_t *m, uint8_t id, void* ptr_data, uint8_t size))dlsym(marsio_so_handle, "marsio_buff_ctrlzone_set");
+ if(NULL == ptr_marsio_buff_ctrlzone_set){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_ctrlzone_set", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_set_rehash_index = (void (*)(marsio_buff_t *m, uint32_t hash))dlsym(marsio_so_handle, "marsio_buff_set_rehash_index");
+ if(NULL == ptr_marsio_buff_set_rehash_index){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_set_rehash_index", ABBR_MARSIO_LIBRARY_FILE);
+ ptr_marsio_buff_set_rehash_index = fake_marsio_buff_set_rehash_index;
+ //return -1;
+ }
+
+ ptr_marsio_buff_mtod = (char * (*)(marsio_buff_t *m))dlsym(marsio_so_handle, "marsio_buff_mtod");
+ if(NULL == ptr_marsio_buff_mtod){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_mtod", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_datalen = (uint32_t (*)(marsio_buff_t *m))dlsym(marsio_so_handle, "marsio_buff_datalen");
+ if(NULL == ptr_marsio_buff_datalen){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_datalen", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_buflen = (uint32_t (*)(marsio_buff_t *m))dlsym(marsio_so_handle, "marsio_buff_buflen");
+ if(NULL == ptr_marsio_buff_buflen){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_buflen", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ ptr_marsio_buff_clone_with_options = (marsio_buff_t * (*)(struct mr_instance * instance, marsio_buff_t * md, int socket_id, int thread_id, uint16_t options))dlsym(marsio_so_handle, "marsio_buff_clone_with_options");
+ if(NULL == ptr_marsio_buff_clone_with_options){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_clone_with_options", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ /************* note: û��marsio_send_burst_flush()�����������, ������! *****************/
+ ptr_marsio_send_burst_flush = (void (*)(struct mr_sendpath * sendpath, queue_id_t sid))dlsym(marsio_so_handle, "marsio_send_burst_flush");
+ if(NULL == ptr_marsio_send_burst_flush){
+ printf("\033[33m[Warning]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_send_burst_flush", ABBR_MARSIO_LIBRARY_FILE);
+ //go on
+ }
+
+ ptr_marsio_buff_malloc_smartoffload = (marsio_buff_t * (*)(struct mr_vdev *vdev, const char *pkt, unsigned int pkt_len))dlsym(marsio_so_handle, "marsio_buff_malloc_smartoffload");
+ if(NULL == ptr_marsio_buff_malloc_smartoffload){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_malloc_smartoffload", ABBR_MARSIO_LIBRARY_FILE);
+ sleep(1);
+ }
+
+ /* for vlan flipping */
+ if(DEPOLYMENT_MODE_INLINE == sapp_global_val->config.packet_io.depolyment_mode_bin){
+ ptr_marsio_buff_get_metadata = (int (*)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data))dlsym(marsio_so_handle, "marsio_buff_get_metadata");
+ if(NULL == ptr_marsio_buff_get_metadata){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_get_metadata", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+
+ ptr_marsio_buff_set_metadata = (int (*)(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data))dlsym(marsio_so_handle, "marsio_buff_set_metadata");
+ if(NULL == ptr_marsio_buff_set_metadata){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_set_metadata", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+
+ ptr_marsio_buff_get_sid_list = (int (*)(marsio_buff_t *m, uint16_t * out_slist, uint8_t sz_out_slist))dlsym(marsio_so_handle, "marsio_buff_get_sid_list");
+ if(NULL == ptr_marsio_buff_set_metadata){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_get_sid_list", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+ ptr_marsio_buff_set_sid_list = (int (*)(marsio_buff_t *m, uint16_t * slist, uint8_t sz_slist))dlsym(marsio_so_handle, "marsio_buff_set_sid_list");
+ if(NULL == ptr_marsio_buff_set_metadata){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_set_sid_list", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+
+ ptr_marsio_buff_append_sid_list = (int (*)(marsio_buff_t *m, uint16_t * slist, uint8_t sz_slist))dlsym(marsio_so_handle, "marsio_buff_append_sid_list");
+ if(NULL == ptr_marsio_buff_append_sid_list){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_append_sid_list", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+
+ ptr_marsio_buff_prepend_sid_list = (int (*)(marsio_buff_t *m, uint16_t * slist, uint8_t sz_slist))dlsym(marsio_so_handle, "marsio_buff_prepend_sid_list");
+ if(NULL == ptr_marsio_buff_prepend_sid_list){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_prepend_sid_list", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+
+ ptr_marsio_buff_unset_metadata = (int (*)(marsio_buff_t *m, enum mr_buff_metadata_type type))dlsym(marsio_so_handle, "marsio_buff_unset_metadata");
+ if(NULL == ptr_marsio_buff_unset_metadata){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_unset_metadata", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+
+ ptr_marsio_buff_set_ctrlbuf = (void (*)(marsio_buff_t *m))dlsym(marsio_so_handle, "marsio_buff_set_ctrlbuf");
+ if(NULL == ptr_marsio_buff_set_ctrlbuf){
+ printf("\033[33m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_buff_set_ctrlbuf", ABBR_MARSIO_LIBRARY_FILE);
+ //return -1; /* Ϊ����ǰ����mrzcpd�ɰ�, �˴��Ȳ����ش���, ֻ��vlan_flipping��ʧЧ */
+ sleep(1);
+ }
+ }
+
+ ptr_marsio_destory = (int (*)(struct mr_instance *instance))dlsym(marsio_so_handle, "marsio_destory");
+ if(NULL == ptr_marsio_destory){
+ printf("\033[1;31;40m[Error]dlsym function '%s' from '%s' failed!\033[0m\n", "marsio_destory", ABBR_MARSIO_LIBRARY_FILE);
+ return -1;
+ }
+
+ return 0;
+}
+
+int marsio_send_burst_with_options_for_tcpdumpmesa(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[],
+ int nr_mbufs, uint16_t options)
+{
+ raw_pkt_t rawpkt;
+ char *rawpkt_data;
+ uint32_t rawpkt_len;
+
+ if(G_PKT_DUMP_SW != 0){
+ rawpkt_data = ptr_marsio_buff_mtod(mbufs[0]);
+ rawpkt_len = ptr_marsio_buff_buflen(mbufs[0]);
+ rawpkt.magic_num = RAW_PKT_MAGIC_NUM;
+ rawpkt.low_layer_type = ADDR_TYPE_MAC;
+ rawpkt.raw_pkt_data = rawpkt_data;
+ rawpkt.raw_pkt_len = rawpkt_len;
+ rawpkt.__lib_raw_pkt_data = rawpkt_data;
+ rawpkt.__lib_raw_pkt_len = rawpkt_len;
+
+ cycle_pkt_dump_by_classify(sid, &rawpkt, PKT_CLASSIFY_INJECT);
+ }
+
+ return ptr_marsio_send_burst_with_options(sendpath, sid, mbufs, nr_mbufs, options);
+}
+
+
+unsigned int marsio_get_vlan_id_from_mbuff(void *pkt_reference)
+{
+ unsigned int vlan_id = 0;
+
+ if(ptr_marsio_buff_get_metadata){
+ ptr_marsio_buff_get_metadata((marsio_buff_t *)pkt_reference, MR_BUFF_METADATA_VLAN_TCI, &vlan_id, sizeof(int));
+ }
+
+ return vlan_id;
+}
+
+int marsio_get_route_dir_from_mbuff(void *pkt_reference)
+{
+ int dir = -1;
+
+ if(ptr_marsio_buff_get_metadata){
+ ptr_marsio_buff_get_metadata((marsio_buff_t *)pkt_reference, MR_BUFF_DIR, &dir, sizeof(int));
+ }
+
+ return dir;
+}
+
+
+int marsio_set_vlan_id_to_mbuff(void *pkt_reference, unsigned int vlan_id_host_order)
+{
+ int ret = 0;
+ if(ptr_marsio_buff_set_metadata){
+ ret = ptr_marsio_buff_set_metadata((marsio_buff_t *)pkt_reference, MR_BUFF_METADATA_VLAN_TCI, &vlan_id_host_order, sizeof(int));
+ }
+
+ return ret;
+}
+
+
+int marsio_dl_io_init(int argc, char *argv[])
+{
+ int i, ret;
+ char app_name[32];
+ int max_send_queue_num;
+
+ if(marsio_dl_get_function_entry() < 0){
+ printf("\033[1;31;40m[Error]dlopen marsio.so symbol failed!\033[0m\n");
+ return -1;
+ }
+
+ sapp_marsio4_instance = ptr_marsio_create();
+ if(NULL == sapp_marsio4_instance) {
+ fprintf(stderr,"%s\n","marsio_create error!\n");
+ return -1;
+ }
+
+ if(NET_CONN_SERIAL_GDEV == g_marsio4_topology_mode){
+ if(g_mr4_device_num != 1){
+ printf("\033[1;31;40m[Error] in inline mode, capture device num is %d!\033[0m\n", g_mr4_device_num);
+ return -1;
+ }
+ }else if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
+ if(g_mr4_device_num != 1){
+ printf("\033[1;31;40m[Error] in transparent mode, capture device num is %d!\033[0m\n", g_mr4_device_num);
+ return -1;
+ }
+ }
+
+ g_mario4_io_handle = (marsio4_io_handle *)SAPP_GLOBAL_ALLOC(sizeof(marsio4_io_handle) * g_marsio4_work_thread_num);
+ ptr_marsio_option_set(sapp_marsio4_instance, MARSIO_OPT_THREAD_NUM, &g_marsio4_work_thread_num, sizeof(int));
+
+ if(sapp_global_val->config.cpu.bind_mask_array_num > 0){
+ cpu_set_t cpu_mask;
+ CPU_ZERO(&cpu_mask);
+ for (i = 0; i < sapp_global_val->config.cpu.bind_mask_array_num; i++)
+ {
+ CPU_SET(sapp_global_val->config.cpu.bind_mask_array[i], &cpu_mask);
+ }
+ ret = ptr_marsio_option_set(sapp_marsio4_instance, MARSIO_OPT_THREAD_MASK_IN_CPUSET, &cpu_mask, sizeof(cpu_mask));
+ if (ret < 0)
+ {
+ printf("\033[1;31;40m[Error] marsio set CPU->bind_mask failed!\033[0m\n");
+ return -1;
+ }
+ }
+
+ ptr_marsio_init(sapp_marsio4_instance, sapp_global_val->config.system.instance_name);
+
+ g_mr4_dev_up_handle_set = (struct mr_vdev **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
+ g_mr4_dev_down_handle_set = (struct mr_vdev **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
+ g_mr4_sendpath_up_set = (struct mr_sendpath **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
+ g_mr4_sendpath_down_set = (struct mr_sendpath **)SAPP_GLOBAL_ALLOC(sizeof(void *) * g_mr4_device_num);
+
+ max_send_queue_num = sapp_global_val->config.cpu.worker_threads + sapp_global_val->config.cpu.send_only_threads_max_num;
+
+ for(i = 0; i < g_mr4_device_num; i++){
+ g_mr4_dev_up_handle_set[i] = ptr_marsio_open_device(sapp_marsio4_instance, g_mr4_up_device_name[i],
+ g_marsio4_work_thread_num,
+ max_send_queue_num);
+ if(NULL == g_mr4_dev_up_handle_set[i]){
+ printf("\033[1;31;40m[Error]Open device '%s' error, please check sapp.toml->packet_io.interface!\033[0m\n",
+ g_mr4_up_device_name[i]);
+ return -1;
+ }
+ g_mr4_sendpath_up_set[i] = ptr_marsio_sendpath_create_by_vdev(g_mr4_dev_up_handle_set[i]);
+
+ if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
+ g_mr4_dev_down_handle_set[i] = ptr_marsio_open_device(sapp_marsio4_instance, g_mr4_down_device_name[i],
+ g_marsio4_work_thread_num,
+ max_send_queue_num);
+ if(NULL == g_mr4_dev_down_handle_set[i]){
+ printf("\033[1;31;40m[Error]Open device '%s' error, please check sapp.toml->packet_io.interface!\033[0m\n",
+ g_mr4_up_device_name[i]);
+ return -1;
+ }
+ g_mr4_sendpath_down_set[i] = ptr_marsio_sendpath_create_by_vdev(g_mr4_dev_down_handle_set[i]);
+ }
+ }
+
+ return 0;
+}
+
+void marsio_dl_io_run(void)
+{
+ int i = 0, ret;
+
+ for(i = 0; i < g_marsio4_work_thread_num; i++)
+ {
+ marsio4_work_thread_seq[i] = i;
+ ret = pthread_create(&(marsio4_work_tid[i]), NULL, marsio4_worker, (void *) &(marsio4_work_thread_seq[i]));
+ assert(0 == ret);
+ sapp_global_val->individual_fixed.thread_obtain_id[i] = marsio4_work_tid[i];
+ }
+}
+
+void marsio_dl_io_destroy(void)
+{
+ int i;
+
+ for(i = 0; i < g_mr4_device_num; i++){
+ ptr_marsio_close_device(g_mr4_dev_up_handle_set[i]);
+ ptr_marsio_sendpath_destory(g_mr4_sendpath_up_set[i]);
+ if(NET_CONN_SERIAL_2CARD == g_marsio4_topology_mode){
+ ptr_marsio_close_device(g_mr4_dev_down_handle_set[i]);
+ ptr_marsio_sendpath_destory(g_mr4_sendpath_down_set[i]);
+ }
+ }
+
+ SAPP_GLOBAL_FREE(g_mr4_dev_up_handle_set);
+ SAPP_GLOBAL_FREE(g_mr4_sendpath_up_set);
+ SAPP_GLOBAL_FREE(g_mr4_dev_down_handle_set);
+ SAPP_GLOBAL_FREE(g_mr4_sendpath_down_set);
+
+ SAPP_GLOBAL_FREE(g_mario4_io_handle);
+ g_mr4_device_num = 0;
+
+ ptr_marsio_destory(sapp_marsio4_instance);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/src/packet_io/sapp_inject.c b/src/packet_io/sapp_inject.c
index 97fdf61..68e8eb2 100644
--- a/src/packet_io/sapp_inject.c
+++ b/src/packet_io/sapp_inject.c
@@ -86,6 +86,16 @@ int sapp_inject_pkt(struct streaminfo *stream, enum sapp_inject_opt sio, const v
return ret;
}
+int sapp_inject_ctrl_pkt(struct streaminfo *stream, enum sapp_inject_opt sio, const void *payload, int payload_len, unsigned char snd_routedir)
+{
+ struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream;
+ stream_pr->is_send_ctrl_pkt=1;
+ int ret=sapp_inject_pkt(stream, SIO_DEFAULT, payload, payload_len, snd_routedir);
+ stream_pr->is_send_ctrl_pkt=0;
+
+ return ret;
+}
+
#ifdef __cplusplus
}
diff --git a/src/packet_io/sendpacket.c b/src/packet_io/sendpacket.c
index 50b924e..afaeae0 100644
--- a/src/packet_io/sendpacket.c
+++ b/src/packet_io/sendpacket.c
@@ -3228,7 +3228,6 @@ int MESA_inject_pkt(struct streaminfo *stream, const char *payload, int payload_
#endif
-
int MESA_inject_pkt_feedback(struct streaminfo *stream, const char *payload, int payload_len,
const void *ext_raw_pkt, UCHAR snd_routedir,
char *feedback_buf, int *feedback_buf_len)
@@ -3404,6 +3403,15 @@ int __sapp_inject_pkt(struct streaminfo *raw_stream, enum sapp_inject_opt sio,
{
((raw_pkt_t *)raw_pkt)->prepend_list=raw_stream_pr->sid_prepend_list;
}
+ if (raw_stream_pr->stream_trace_id != 0)
+ {
+ ((raw_pkt_t *)raw_pkt)->stream_trace_id = raw_stream_pr->stream_trace_id;
+ }
+ if (raw_stream_pr->is_send_ctrl_pkt != 0)
+ {
+ ((raw_pkt_t *)raw_pkt)->is_send_ctrl_pkt = raw_stream_pr->is_send_ctrl_pkt;
+ ((raw_pkt_t *)raw_pkt)->payload_len=payload_len;
+ }
/* injectʹ�õ���routedir, �˴�ת����stream dir,
ע��: ��������Ķ������ܲ����ɵ�ǰ��������, ����kni, �Ǵ����������յ����ݰ�, ��ע����·��,