[PACKET_IO] add pio_packet structure for pcap_live/pcap_file mode
This commit is contained in:
@@ -58,6 +58,9 @@ struct packet_io_config {
|
||||
|
||||
/* promiscuous value */
|
||||
int promisc;
|
||||
|
||||
/* marsio ctrlzone id */
|
||||
int mr_ctrlzone_id;
|
||||
};
|
||||
|
||||
struct lib_config {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: packet_queue.h
|
||||
* Description: packet queue structure and api
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-07-15
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../sdk/include/packet.h"
|
||||
|
||||
#define PKT_QUEUE_MAX_NUM 256
|
||||
|
||||
#define SET_PKT_LEN(p, len) do { \
|
||||
(p)->pkt_len = (len); \
|
||||
} while(0)
|
||||
|
||||
#define GET_PKT_DIRECT_DATA(p) (uint8_t *)((p) + 1)
|
||||
|
||||
struct packet_queue {
|
||||
struct packet *top;
|
||||
struct packet *bot;
|
||||
uint32_t len;
|
||||
pthread_mutex_t mutex_q;
|
||||
};
|
||||
|
||||
void packet_enqueue(struct packet_queue *, struct packet *);
|
||||
struct packet *packet_dequeue(struct packet_queue *);
|
||||
void release_packet_queue(struct packet_queue *);
|
||||
@@ -9,9 +9,9 @@
|
||||
*/
|
||||
|
||||
#include "../../sdk/include/utils.h"
|
||||
#include "packet_queue.h"
|
||||
#include "pio_packet_queue.h"
|
||||
|
||||
void packet_enqueue(struct packet_queue *q, struct packet *p)
|
||||
void pio_packet_enqueue(struct pio_packet_queue *q, struct pio_packet *p)
|
||||
{
|
||||
if (nullptr == p)
|
||||
return;
|
||||
@@ -32,9 +32,9 @@ void packet_enqueue(struct packet_queue *q, struct packet *p)
|
||||
q->len++;
|
||||
}
|
||||
|
||||
struct packet *packet_dequeue(struct packet_queue *q)
|
||||
struct pio_packet *pio_packet_dequeue(struct pio_packet_queue *q)
|
||||
{
|
||||
struct packet *p = NULL;
|
||||
struct pio_packet *p = NULL;
|
||||
|
||||
/* if the queue is empty there are no packets left. */
|
||||
if (q->len == 0) {
|
||||
@@ -58,17 +58,19 @@ struct packet *packet_dequeue(struct packet_queue *q)
|
||||
|
||||
p->next = nullptr;
|
||||
p->prev = nullptr;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void release_packet_queue(struct packet_queue *q)
|
||||
void release_pio_packet_queue(struct pio_packet_queue *q)
|
||||
{
|
||||
if (nullptr == q) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (q->len != 0) {
|
||||
struct packet *p = packet_dequeue(q);
|
||||
struct pio_packet *p = pio_packet_dequeue(q);
|
||||
q->len--;
|
||||
FREE(p);
|
||||
}
|
||||
}
|
||||
62
src/common/pio_packet_queue.h
Normal file
62
src/common/pio_packet_queue.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: pio_packet_queue.h
|
||||
* Description: pio packet queue structure and api
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-07-15
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PKT_QUEUE_MAX_NUM 256
|
||||
|
||||
#define CUSTOM_ZONE_LEN 64
|
||||
#define ETHERNET_HEADER_LEN 14
|
||||
#define DEFAULT_MTU 1500
|
||||
#define DEFAULT_PACKET_SIZE (CUSTOM_ZONE_LEN + DEFAULT_MTU + ETHERNET_HEADER_LEN)
|
||||
|
||||
#define SIZE_OF_PIO_PACKET (DEFAULT_PACKET_SIZE + sizeof(struct pio_packet))
|
||||
|
||||
/*
|
||||
* @brief pcap_live/pcap_file mode packet structure
|
||||
*
|
||||
* |<-pkt_hdr |<-pkt_payload
|
||||
* | |
|
||||
* | struct pio_packet | custom zone | L2 header | ...... |
|
||||
* 64bytes 14bytes 1500bytes
|
||||
*
|
||||
* custom zone: user can set custom field
|
||||
* pkt_payload: received packet data
|
||||
**/
|
||||
struct pio_packet {
|
||||
/* pkt header pointer */
|
||||
void *pkt_hdr;
|
||||
|
||||
/* pkt length */
|
||||
uint64_t pkt_len;
|
||||
|
||||
/* pkt payload pointer */
|
||||
void *pkt_payload;
|
||||
|
||||
/* reference counts */
|
||||
uint64_t ref_cnt;
|
||||
|
||||
struct pio_packet *prev;
|
||||
|
||||
struct pio_packet *next;
|
||||
};
|
||||
|
||||
struct pio_packet_queue {
|
||||
struct pio_packet *top;
|
||||
struct pio_packet *bot;
|
||||
uint32_t len;
|
||||
pthread_mutex_t mutex_q;
|
||||
};
|
||||
|
||||
void pio_packet_enqueue(struct pio_packet_queue *, struct pio_packet *);
|
||||
struct pio_packet *pio_packet_dequeue(struct pio_packet_queue *);
|
||||
void release_pio_packet_queue(struct pio_packet_queue *);
|
||||
14
src/main.cpp
14
src/main.cpp
@@ -29,18 +29,20 @@ void packet_io_loop(struct packet_io_loop_arg *arg)
|
||||
int fetch_num = packet_io_device_rx(arg->dev, arg->thread_id, &rx_pkt, 1);
|
||||
if(fetch_num > 0)
|
||||
{
|
||||
/*
|
||||
event = session_manager_commit(rx_pkt);
|
||||
while(event)
|
||||
{
|
||||
plugin_manager_dispatch(event);
|
||||
event = session_manager_fetch_event();
|
||||
}
|
||||
|
||||
}*/
|
||||
printf("fetch_num:%d\n", fetch_num);
|
||||
//clean session_manager event queue
|
||||
packet_io_device_tx(arg->dev, arg->thread_id, &rx_pkt, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("no fetch num\n");
|
||||
//dispatch to time event
|
||||
|
||||
//dispatch to trigger polling event
|
||||
@@ -79,9 +81,11 @@ int main(int argc, char ** argv)
|
||||
/* packet io init */
|
||||
packet_io_init("stellar", g_engine_instance.config.packet_io.mode, 2);
|
||||
|
||||
session_manager_session_event_register(http_decoder, SESSION_TYPE_HTTP);
|
||||
|
||||
|
||||
//session_manager_session_event_register(http_decoder, SESSION_TYPE_HTTP);
|
||||
struct packet_io_loop_arg arg;
|
||||
while (1) {
|
||||
//packet_io_loop();
|
||||
}
|
||||
//create_worker_thread
|
||||
|
||||
//main_loop
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
add_library(packet_io
|
||||
../common/global_var.cpp
|
||||
../common/packet_queue.cpp
|
||||
../common/pio_packet_queue.cpp
|
||||
../common/time_helper.cpp
|
||||
packet_io.cpp
|
||||
pcap_live_mode/pio_pcap_live.cpp
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "marsio.h"
|
||||
#include <marsio.h>
|
||||
|
||||
/*
|
||||
* dll is short for dynamic link lib
|
||||
|
||||
@@ -63,6 +63,18 @@ struct pio_instance_operations pio_instance_ops_array[PACKET_IO_RUN_MODE_MAX] =
|
||||
struct packet_io_instance *
|
||||
packet_io_instance_create(const char *inst_name, const enum packet_io_run_mode mode, const int wrk_thread_num)
|
||||
{
|
||||
if (nullptr == inst_name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mode < PACKET_IO_RUN_MODE_PCAP_FILE || mode >= PACKET_IO_RUN_MODE_MAX) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (wrk_thread_num < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct packet_io_instance *pio_instance = CALLOC(struct packet_io_instance, 1);
|
||||
if (nullptr == pio_instance) {
|
||||
log_error(ST_ERR_MEM_ALLOC, "packet_io instance alloc failed.");
|
||||
@@ -156,16 +168,14 @@ void packet_io_pkts_free(struct packet_io_instance *pinst, uint32_t qid, struct
|
||||
|
||||
}
|
||||
|
||||
static int packet_copy_data_offset(struct packet *p, uint32_t offset, const uint8_t *data, uint32_t data_len)
|
||||
static int packet_copy_data_offset(uint8_t *ptr, uint32_t offset, const uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
memcpy(GET_PKT_DIRECT_DATA(p) + offset, data, data_len);
|
||||
memcpy(ptr + offset, data, data_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int packet_copy_data(struct packet *p, const uint8_t *pkt_data, uint32_t pkt_len)
|
||||
{
|
||||
SET_PKT_LEN(p, (size_t)pkt_len);
|
||||
|
||||
return packet_copy_data_offset(p, 0, pkt_data, pkt_len);
|
||||
int packet_copy_data(uint8_t *ptr, const uint8_t *pkt_data, uint32_t pkt_len)
|
||||
{
|
||||
return packet_copy_data_offset(ptr, 0, pkt_data, pkt_len);
|
||||
}
|
||||
@@ -144,4 +144,4 @@ int packet_io_device_tx(struct packet_io_device *pdev, uint32_t txq_id, struct p
|
||||
**/
|
||||
void packet_io_pkts_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts);
|
||||
|
||||
int packet_copy_data(struct packet *p, const uint8_t *pkt_data, uint32_t pkt_len);
|
||||
int packet_copy_data(uint8_t *ptr, const uint8_t *pkt_data, uint32_t pkt_len);
|
||||
@@ -287,7 +287,7 @@ int pio_pcap_file_device_close(struct packet_io_device *pdev)
|
||||
|
||||
for (uint32_t i = 0; i < PKT_QUEUE_MAX_NUM; i++) {
|
||||
if (pdev->entity.pcap_file_dev_ctx->pkt_queues[i].len != 0) {
|
||||
release_packet_queue(&pdev->entity.pcap_file_dev_ctx->pkt_queues[i]);
|
||||
release_pio_packet_queue(&pdev->entity.pcap_file_dev_ctx->pkt_queues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,12 +299,16 @@ int pio_pcap_file_device_close(struct packet_io_device *pdev)
|
||||
void pcap_file_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_hdr, u_char *pkt)
|
||||
{
|
||||
struct pio_pcap_file_device_context *pfile_dev_ctx = (struct pio_pcap_file_device_context *)user;
|
||||
struct packet *p = CALLOC(struct packet, 1);
|
||||
struct pio_packet *p = (struct pio_packet *)malloc(SIZE_OF_PIO_PACKET);
|
||||
if (nullptr == p) {
|
||||
return;
|
||||
}
|
||||
memset(p, 0, SIZE_OF_PIO_PACKET);
|
||||
|
||||
if (packet_copy_data(p, pkt, pkt_hdr->caplen)) {
|
||||
p->pkt_hdr = p;
|
||||
p->pkt_payload = (uint8_t *)p + CUSTOM_ZONE_LEN;
|
||||
p->pkt_len = pkt_hdr->caplen;
|
||||
if (packet_copy_data((uint8_t *)p->pkt_payload, (uint8_t *)pkt, pkt_hdr->caplen)) {
|
||||
FREE(p);
|
||||
return;
|
||||
}
|
||||
@@ -314,10 +318,10 @@ void pcap_file_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_hdr, u_c
|
||||
hash_id = decode_packet(p) % nr_rxq;
|
||||
packet_enqueue(&pfile_dev_ctx->pkt_queues[hash_id], p);
|
||||
*/
|
||||
/*
|
||||
int rxq_id = 0;
|
||||
pthread_mutex_lock(&pfile_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
packet_enqueue(&pfile_dev_ctx->pkt_queues[rxq_id], p);
|
||||
pthread_mutex_unlock(&pfile_dev_ctx->pkt_queues[rxq_id].mutex_q); */
|
||||
pio_packet_enqueue(&pfile_dev_ctx->pkt_queues[rxq_id], p);
|
||||
pthread_mutex_unlock(&pfile_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
}
|
||||
|
||||
static int pcap_file_dispatch(struct pio_pcap_file_device_context *pfile_dev_ctx, uint32_t nr_rxq, uint32_t rxq_id,
|
||||
@@ -349,12 +353,12 @@ static int pcap_file_dispatch(struct pio_pcap_file_device_context *pfile_dev_ctx
|
||||
//TODO: close pcap file
|
||||
} else {
|
||||
// success
|
||||
struct packet *p = nullptr;
|
||||
struct pio_packet *p = nullptr;
|
||||
int i = 0;
|
||||
pthread_mutex_lock(&pfile_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
do {
|
||||
p = packet_dequeue(&pfile_dev_ctx->pkt_queues[rxq_id]);
|
||||
pkts[i] = p;
|
||||
p = pio_packet_dequeue(&pfile_dev_ctx->pkt_queues[rxq_id]);
|
||||
pkts[i] = (struct packet *)p;
|
||||
i++;
|
||||
} while (p != nullptr && (i < nr_pkts));
|
||||
pthread_mutex_unlock(&pfile_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
@@ -603,9 +607,12 @@ int pio_pcap_file_device_send(struct packet_io_device *pdev, uint32_t txq_id, st
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pio_pcap_file_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
void pio_pcap_file_device_pkt_free(__unused struct packet_io_device *pdev, __unused uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
{
|
||||
|
||||
for (uint32_t i = 0; i < nr_pkts; i++) {
|
||||
struct pio_packet *p = (struct pio_packet *)pkts[i];
|
||||
FREE(p);
|
||||
}
|
||||
}
|
||||
|
||||
int pio_pcap_file_instance_create(struct packet_io_instance *pinst, __unused int wrk_thread_num)
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
#include <stdint.h>
|
||||
#include <dirent.h>
|
||||
#include <pcap/pcap.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include "../../common/global_var.h"
|
||||
#include "../../common/packet_queue.h"
|
||||
#include "../../common/pio_packet_queue.h"
|
||||
|
||||
struct pio_pcap_file_instance_context {
|
||||
|
||||
@@ -87,8 +88,8 @@ struct pio_pcap_file_device_context {
|
||||
|
||||
bool is_dir;
|
||||
|
||||
/* rx packet queue */
|
||||
struct packet_queue pkt_queues[PKT_QUEUE_MAX_NUM];
|
||||
/* rx pio packet queue */
|
||||
struct pio_packet_queue pkt_queues[PKT_QUEUE_MAX_NUM];
|
||||
|
||||
struct pcap_file_shared_info shared;
|
||||
};
|
||||
|
||||
@@ -133,7 +133,7 @@ int pio_pcap_live_device_close(struct packet_io_device *pdev)
|
||||
|
||||
for (uint32_t i = 0; i < PKT_QUEUE_MAX_NUM; i++) {
|
||||
if (pdev->entity.pcap_live_dev_ctx->pkt_queues[i].len != 0) {
|
||||
release_packet_queue(&pdev->entity.pcap_live_dev_ctx->pkt_queues[i]);
|
||||
release_pio_packet_queue(&pdev->entity.pcap_live_dev_ctx->pkt_queues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,12 +145,15 @@ int pio_pcap_live_device_close(struct packet_io_device *pdev)
|
||||
static void pcap_live_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_hdr, u_char *pkt)
|
||||
{
|
||||
struct pio_pcap_live_device_context *plive_dev_ctx = (struct pio_pcap_live_device_context *)user;
|
||||
struct packet *p = CALLOC(struct packet, 1);
|
||||
struct pio_packet *p = (struct pio_packet *)malloc(SIZE_OF_PIO_PACKET);
|
||||
if (nullptr == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet_copy_data(p, (uint8_t *)pkt, pkt_hdr->caplen)) {
|
||||
memset(p, 0, sizeof(SIZE_OF_PIO_PACKET));
|
||||
p->pkt_hdr = p;
|
||||
p->pkt_payload = (uint8_t *)p + CUSTOM_ZONE_LEN;
|
||||
p->pkt_len = pkt_hdr->caplen;
|
||||
if (packet_copy_data((uint8_t *)p->pkt_payload, (uint8_t *)pkt, pkt_hdr->caplen)) {
|
||||
FREE(p);
|
||||
return;
|
||||
}
|
||||
@@ -160,10 +163,10 @@ static void pcap_live_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_h
|
||||
hash_id = decode_packet(p) % nr_rxq;
|
||||
packet_enqueue(&pfile_dev_ctx->pkt_queues[hash_id], p);
|
||||
*/
|
||||
/*
|
||||
int rxq_id = 0;
|
||||
pthread_mutex_lock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
packet_enqueue(&plive_dev_ctx->pkt_queues[rxq_id], p);
|
||||
pthread_mutex_unlock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q); */
|
||||
pio_packet_enqueue(&plive_dev_ctx->pkt_queues[rxq_id], p);
|
||||
pthread_mutex_unlock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
}
|
||||
|
||||
int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts)
|
||||
@@ -187,12 +190,12 @@ int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id,
|
||||
} else if (res == 0) {
|
||||
|
||||
} else {
|
||||
struct packet *p = nullptr;
|
||||
struct pio_packet *p = nullptr;
|
||||
int i = 0;
|
||||
pthread_mutex_lock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
do {
|
||||
p = packet_dequeue(&plive_dev_ctx->pkt_queues[rxq_id]);
|
||||
pkts[i] = p;
|
||||
p = pio_packet_dequeue(&plive_dev_ctx->pkt_queues[rxq_id]);
|
||||
pkts[i] = (struct packet *)p;
|
||||
i++;
|
||||
} while (p != nullptr && (i < nr_pkts));
|
||||
pthread_mutex_unlock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
@@ -220,16 +223,21 @@ int pio_pcap_live_device_send(struct packet_io_device *pdev, uint32_t txq_id, st
|
||||
int packet_q_len = nr_pkts;
|
||||
pthread_mutex_lock(&plive_dev_ctx->handle_mutex);
|
||||
for (uint32_t i = 0; i < nr_pkts; i++) {
|
||||
res = pcap_sendpacket(plive_dev_ctx->pcap_handle, (u_char *)pkts[i], sizeof(struct packet));
|
||||
struct pio_packet *p = (struct pio_packet *)pkts[i];
|
||||
res = pcap_sendpacket(plive_dev_ctx->pcap_handle, (u_char *)p->pkt_payload, p->pkt_len);
|
||||
}
|
||||
pthread_mutex_unlock(&plive_dev_ctx->handle_mutex);
|
||||
|
||||
/*TODO: when to free pio_packet? */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pio_pcap_live_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
void pio_pcap_live_device_pkt_free(__unused struct packet_io_device *pdev, __unused uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
{
|
||||
|
||||
for (uint32_t i = 0; i < nr_pkts; i++) {
|
||||
struct pio_packet *p = (struct pio_packet *)pkts[i];
|
||||
FREE(p);
|
||||
}
|
||||
}
|
||||
|
||||
int pio_pcap_live_instance_create(struct packet_io_instance *pinst, __unused int wrk_thread_num)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <pcap/pcap.h>
|
||||
|
||||
#include "../../common/global_var.h"
|
||||
#include "../../common/packet_queue.h"
|
||||
#include "../../common/pio_packet_queue.h"
|
||||
|
||||
#define PCAP_STATE_UP 1
|
||||
#define PCAP_STATE_DOWN 0
|
||||
@@ -51,7 +51,7 @@ struct pio_pcap_live_device_context {
|
||||
int pcap_snaplen;
|
||||
|
||||
/* rx packet queue */
|
||||
struct packet_queue pkt_queues[PKT_QUEUE_MAX_NUM];
|
||||
struct pio_packet_queue pkt_queues[PKT_QUEUE_MAX_NUM];
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
#include "../packet_io.h"
|
||||
|
||||
TEST(PACKET_IO_Test, packet_io_instance_create) {
|
||||
struct packet_io_config ppio_config;
|
||||
struct packet_io_instance *ppio_inst = packet_io_instance_create("stellar", PACKET_IO_RUN_MODE_PCAP_FILE, 2);
|
||||
EXPECT_NE(ppio_inst, nullptr);
|
||||
}
|
||||
|
||||
TEST(PACKET_IO_Test, packet_io_open_device) {
|
||||
struct packet_io_config ppio_config;
|
||||
struct packet_io_instance *ppio_inst = packet_io_instance_create("stellar", PACKET_IO_RUN_MODE_PCAP_FILE, 2);
|
||||
|
||||
Reference in New Issue
Block a user