diff options
| author | 刘学利 <[email protected]> | 2023-02-28 03:17:18 +0000 |
|---|---|---|
| committer | 刘学利 <[email protected]> | 2023-02-28 03:17:18 +0000 |
| commit | e9974578ead7c7cb9f0c7e758e24c7e7b9b2aeac (patch) | |
| tree | 94d23f992619aa3ca8b356a8aba39e09d0aad367 | |
| parent | 35ae368647c22ec75ae7034b6f8c29af4f40351e (diff) | |
overlay为NF模式下,无条件转发数据包,并携带SID、流ID等
| -rw-r--r-- | include/private/stream_internal.h | 13 | ||||
| -rw-r--r-- | include/public/stream_inc/sapp_inject.h | 1 | ||||
| -rw-r--r-- | include/public/stream_inc/stream_control.h | 1 | ||||
| -rw-r--r-- | include/public/stream_inc/stream_inject.h | 1 | ||||
| -rw-r--r-- | src/dealpkt/callapp.c | 15 | ||||
| -rw-r--r-- | src/dealpkt/deal_tcp.c | 5 | ||||
| -rw-r--r-- | src/dealpkt/deal_udp.c | 8 | ||||
| -rw-r--r-- | src/dealpkt/plug_support.c | 3924 | ||||
| -rw-r--r-- | src/packet_io/packet_io_marsio.c | 2745 | ||||
| -rw-r--r-- | src/packet_io/sapp_inject.c | 10 | ||||
| -rw-r--r-- | src/packet_io/sendpacket.c | 10 |
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(¤t_cpu_mask); - - if(pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), ¤t_cpu_mask) < 0){ - return -1; - } - - int tot_cpu_core = get_nprocs(); - int tot_cpu_set_count = CPU_COUNT(¤t_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, ¤t_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(¤t_cpu_mask);
+
+ if(pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), ¤t_cpu_mask) < 0){
+ return -1;
+ }
+
+ int tot_cpu_core = get_nprocs();
+ int tot_cpu_set_count = CPU_COUNT(¤t_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, ¤t_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, �Ǵ����������յ����ݰ�, ��ע����·��, |
