feature: packet IO support IP reassembly
This commit is contained in:
@@ -1,267 +1,50 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "toml.h"
|
||||
#include "pcap_io.h"
|
||||
#include "marsio_io.h"
|
||||
#include "mars_io.h"
|
||||
#include "log_internal.h"
|
||||
#include "utils_internal.h"
|
||||
|
||||
#define PACKET_IO_LOG_ERROR(format, ...) STELLAR_LOG_ERROR(__thread_local_logger, "packet io", format, ##__VA_ARGS__)
|
||||
#define PACKET_IO_LOG_INFO(format, ...) STELLAR_LOG_INFO(__thread_local_logger, "packet io", format, ##__VA_ARGS__)
|
||||
|
||||
struct packet_io
|
||||
{
|
||||
struct packet_io_config *cfg;
|
||||
void *handle;
|
||||
|
||||
void *(*new_func)(const struct packet_io_config *cfg);
|
||||
void *(*new_func)(const char *toml_file);
|
||||
void (*free_func)(void *handle);
|
||||
int (*isbreak_func)(void *handle);
|
||||
|
||||
int (*init_func)(void *handle, uint16_t thr_idx);
|
||||
uint16_t (*ingress_func)(void *handle, uint16_t thr_idx, struct packet *pkts, uint16_t nr_pkts);
|
||||
void (*egress_func)(void *handle, uint16_t thr_idx, struct packet *pkts, uint16_t nr_pkts);
|
||||
void (*drop_func)(void *handle, uint16_t thr_idx, struct packet *pkts, uint16_t nr_pkts);
|
||||
int (*recv_func)(void *handle, uint16_t thr_idx, struct packet *pkts[], int nr_pkts);
|
||||
void (*send_func)(void *handle, uint16_t thr_idx, struct packet *pkts[], int nr_pkts);
|
||||
void (*drop_func)(void *handle, uint16_t thr_idx, struct packet *pkts[], int nr_pkts);
|
||||
void (*yield_func)(void *handle, uint16_t thr_idx);
|
||||
void (*polling_func)(void *handle, uint16_t thr_idx);
|
||||
struct packet_io_stat *(*stat_func)(void *handle, uint16_t thr_idx);
|
||||
};
|
||||
|
||||
static struct packet_io_config *packet_io_config_new(const char *toml_file)
|
||||
{
|
||||
int ret = -1;
|
||||
const char *ptr;
|
||||
char *ptr_mode = NULL;
|
||||
char *ptr_pcap_path = NULL;
|
||||
char *ptr_app_symbol = NULL;
|
||||
char *ptr_dev_symbol = NULL;
|
||||
char errbuf[200];
|
||||
FILE *fp = NULL;
|
||||
toml_table_t *root = NULL;
|
||||
toml_table_t *table = NULL;
|
||||
toml_array_t *mask;
|
||||
|
||||
struct packet_io_config *cfg = (struct packet_io_config *)calloc(1, sizeof(struct packet_io_config));
|
||||
if (cfg == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fp = fopen(toml_file, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file %s open failed, %s", toml_file, strerror(errno));
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
root = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||
if (root == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file %s parse failed, %s", toml_file, errbuf);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
table = toml_table_in(root, "packet_io");
|
||||
if (table == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file %s missing packet_io", toml_file);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
ptr = toml_raw_in(table, "mode");
|
||||
if (ptr == NULL || toml_rtos(ptr, &ptr_mode) != 0)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.mode");
|
||||
goto error_out;
|
||||
}
|
||||
if (strcmp(ptr_mode, "pcapfile") == 0)
|
||||
{
|
||||
cfg->mode = PACKET_IO_PCAPFILE;
|
||||
}
|
||||
else if (strcmp(ptr_mode, "pcaplist") == 0)
|
||||
{
|
||||
cfg->mode = PACKET_IO_PCAPLIST;
|
||||
}
|
||||
else if (strcmp(ptr_mode, "marsio") == 0)
|
||||
{
|
||||
cfg->mode = PACKET_IO_MARSIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file invalid packet_io.mode %s", ptr);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (cfg->mode == PACKET_IO_PCAPFILE || cfg->mode == PACKET_IO_PCAPLIST)
|
||||
{
|
||||
ptr = toml_raw_in(table, "pcap_path");
|
||||
if (ptr == NULL || toml_rtos(ptr, &ptr_pcap_path) != 0)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.pcap_path");
|
||||
goto error_out;
|
||||
}
|
||||
strcpy(cfg->pcap_path, ptr_pcap_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = toml_raw_in(table, "app_symbol");
|
||||
if (ptr == NULL || toml_rtos(ptr, &ptr_app_symbol) != 0)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.app_symbol");
|
||||
goto error_out;
|
||||
}
|
||||
strcpy(cfg->app_symbol, ptr_app_symbol);
|
||||
|
||||
ptr = toml_raw_in(table, "dev_symbol");
|
||||
if (ptr == NULL || toml_rtos(ptr, &ptr_dev_symbol) != 0)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.dev_symbol");
|
||||
goto error_out;
|
||||
}
|
||||
strcpy(cfg->dev_symbol, ptr_dev_symbol);
|
||||
}
|
||||
|
||||
ptr = toml_raw_in(table, "nr_worker_thread");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.nr_worker_thread");
|
||||
goto error_out;
|
||||
}
|
||||
cfg->nr_worker_thread = atoi(ptr);
|
||||
if (cfg->nr_worker_thread == 0 || cfg->nr_worker_thread > MAX_THREAD_NUM)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file invalid packet_io.nr_worker_thread %d, range [1, %d]", cfg->nr_worker_thread, MAX_THREAD_NUM);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
mask = toml_array_in(table, "cpu_mask");
|
||||
if (mask == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.cpu_mask");
|
||||
goto error_out;
|
||||
}
|
||||
for (uint16_t i = 0; i < cfg->nr_worker_thread; i++)
|
||||
{
|
||||
ptr = toml_raw_at(mask, i);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.cpu_mask[%d]", i);
|
||||
goto error_out;
|
||||
}
|
||||
cfg->cpu_mask[i] = atoi(ptr);
|
||||
}
|
||||
|
||||
ptr = toml_raw_in(table, "idle_yield_interval_ms");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file missing packet_io.idle_yield_interval_ms");
|
||||
goto error_out;
|
||||
}
|
||||
cfg->idle_yield_interval_ms = atoll(ptr);
|
||||
if (cfg->idle_yield_interval_ms > 60000)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("config file invalid packet_io.idle_yield_interval_ms %d, range [0, %d]", cfg->idle_yield_interval_ms, 60000);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
error_out:
|
||||
if (ptr_mode)
|
||||
{
|
||||
free(ptr_mode);
|
||||
}
|
||||
if (ptr_pcap_path)
|
||||
{
|
||||
free(ptr_pcap_path);
|
||||
}
|
||||
if (ptr_app_symbol)
|
||||
{
|
||||
free(ptr_app_symbol);
|
||||
}
|
||||
if (ptr_dev_symbol)
|
||||
{
|
||||
free(ptr_dev_symbol);
|
||||
}
|
||||
if (root)
|
||||
{
|
||||
toml_free(root);
|
||||
}
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
free(cfg);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cfg;
|
||||
}
|
||||
}
|
||||
|
||||
static void packet_io_config_free(struct packet_io_config *cfg)
|
||||
{
|
||||
if (cfg)
|
||||
{
|
||||
free(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void packet_io_config_print(const struct packet_io_config *cfg)
|
||||
{
|
||||
if (cfg)
|
||||
{
|
||||
PACKET_IO_LOG_INFO("packet_io.mode : %s", cfg->mode == PACKET_IO_PCAPFILE ? "pcapfile" : (cfg->mode == PACKET_IO_PCAPLIST ? "pcaplist" : "marsio"));
|
||||
if (cfg->mode == PACKET_IO_PCAPFILE || cfg->mode == PACKET_IO_PCAPLIST)
|
||||
{
|
||||
PACKET_IO_LOG_INFO("packet_io.pcap_path : %s", cfg->pcap_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
PACKET_IO_LOG_INFO("packet_io.app_symbol : %s", cfg->app_symbol);
|
||||
PACKET_IO_LOG_INFO("packet_io.dev_symbol : %s", cfg->dev_symbol);
|
||||
}
|
||||
PACKET_IO_LOG_INFO("packet_io.nr_worker_thread : %d", cfg->nr_worker_thread);
|
||||
for (uint16_t i = 0; i < cfg->nr_worker_thread; i++)
|
||||
{
|
||||
PACKET_IO_LOG_INFO("packet_io.cpu_mask[%03d] : %d", i, cfg->cpu_mask[i]);
|
||||
}
|
||||
PACKET_IO_LOG_INFO("packet_io.idle_yield_interval_ms : %lu", cfg->idle_yield_interval_ms);
|
||||
}
|
||||
}
|
||||
|
||||
struct packet_io *packet_io_new(const char *toml_file)
|
||||
{
|
||||
char mode[64] = {0};
|
||||
struct packet_io *pkt_io = (struct packet_io *)calloc(1, sizeof(struct packet_io));
|
||||
if (pkt_io == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pkt_io->cfg = packet_io_config_new(toml_file);
|
||||
if (pkt_io->cfg == NULL)
|
||||
load_toml_str_config(toml_file, "packet_io.mode", mode);
|
||||
if (strcmp(mode, "marsio") == 0)
|
||||
{
|
||||
free(pkt_io);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
packet_io_config_print(pkt_io->cfg);
|
||||
|
||||
if (pkt_io->cfg->mode == PACKET_IO_MARSIO)
|
||||
{
|
||||
pkt_io->new_func = marsio_io_new;
|
||||
pkt_io->free_func = marsio_io_free;
|
||||
pkt_io->isbreak_func = marsio_io_isbreak;
|
||||
pkt_io->init_func = marsio_io_init;
|
||||
pkt_io->ingress_func = marsio_io_ingress;
|
||||
pkt_io->egress_func = marsio_io_egress;
|
||||
pkt_io->drop_func = marsio_io_drop;
|
||||
pkt_io->yield_func = marsio_io_yield;
|
||||
pkt_io->stat_func = marsio_io_stat;
|
||||
pkt_io->new_func = mars_io_new;
|
||||
pkt_io->free_func = mars_io_free;
|
||||
pkt_io->isbreak_func = mars_io_isbreak;
|
||||
pkt_io->init_func = mars_io_init;
|
||||
pkt_io->recv_func = mars_io_recv;
|
||||
pkt_io->send_func = mars_io_send;
|
||||
pkt_io->drop_func = mars_io_drop;
|
||||
pkt_io->yield_func = mars_io_yield;
|
||||
pkt_io->polling_func = mars_io_polling;
|
||||
pkt_io->stat_func = mars_io_stat;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -269,14 +52,15 @@ struct packet_io *packet_io_new(const char *toml_file)
|
||||
pkt_io->free_func = pcap_io_free;
|
||||
pkt_io->isbreak_func = pcap_io_isbreak;
|
||||
pkt_io->init_func = pcap_io_init;
|
||||
pkt_io->ingress_func = pcap_io_ingress;
|
||||
pkt_io->egress_func = pcap_io_egress;
|
||||
pkt_io->recv_func = pcap_io_recv;
|
||||
pkt_io->send_func = pcap_io_send;
|
||||
pkt_io->drop_func = pcap_io_drop;
|
||||
pkt_io->yield_func = pcap_io_yield;
|
||||
pkt_io->polling_func = pcap_io_polling;
|
||||
pkt_io->stat_func = pcap_io_stat;
|
||||
}
|
||||
|
||||
pkt_io->handle = pkt_io->new_func(pkt_io->cfg);
|
||||
pkt_io->handle = pkt_io->new_func(toml_file);
|
||||
if (pkt_io->handle == NULL)
|
||||
{
|
||||
packet_io_free(pkt_io);
|
||||
@@ -294,10 +78,6 @@ void packet_io_free(struct packet_io *pkt_io)
|
||||
{
|
||||
pkt_io->free_func(pkt_io->handle);
|
||||
}
|
||||
if (pkt_io->cfg)
|
||||
{
|
||||
packet_io_config_free(pkt_io->cfg);
|
||||
}
|
||||
free(pkt_io);
|
||||
pkt_io = NULL;
|
||||
}
|
||||
@@ -313,17 +93,17 @@ int packet_io_init(struct packet_io *pkt_io, uint16_t thr_idx)
|
||||
return pkt_io->init_func(pkt_io->handle, thr_idx);
|
||||
}
|
||||
|
||||
uint16_t packet_io_ingress(struct packet_io *pkt_io, uint16_t thr_idx, struct packet *pkts, uint16_t nr_pkts)
|
||||
int packet_io_recv(struct packet_io *pkt_io, uint16_t thr_idx, struct packet *pkts[], int nr_pkts)
|
||||
{
|
||||
return pkt_io->ingress_func(pkt_io->handle, thr_idx, pkts, nr_pkts);
|
||||
return pkt_io->recv_func(pkt_io->handle, thr_idx, pkts, nr_pkts);
|
||||
}
|
||||
|
||||
void packet_io_egress(struct packet_io *pkt_io, uint16_t thr_idx, struct packet *pkts, uint16_t nr_pkts)
|
||||
void packet_io_send(struct packet_io *pkt_io, uint16_t thr_idx, struct packet *pkts[], int nr_pkts)
|
||||
{
|
||||
pkt_io->egress_func(pkt_io->handle, thr_idx, pkts, nr_pkts);
|
||||
pkt_io->send_func(pkt_io->handle, thr_idx, pkts, nr_pkts);
|
||||
}
|
||||
|
||||
void packet_io_drop(struct packet_io *pkt_io, uint16_t thr_idx, struct packet *pkts, uint16_t nr_pkts)
|
||||
void packet_io_drop(struct packet_io *pkt_io, uint16_t thr_idx, struct packet *pkts[], int nr_pkts)
|
||||
{
|
||||
pkt_io->drop_func(pkt_io->handle, thr_idx, pkts, nr_pkts);
|
||||
}
|
||||
@@ -333,6 +113,11 @@ void packet_io_yield(struct packet_io *pkt_io, uint16_t thr_idx)
|
||||
pkt_io->yield_func(pkt_io->handle, thr_idx);
|
||||
}
|
||||
|
||||
void packet_io_polling(struct packet_io *pkt_io, uint16_t thr_idx)
|
||||
{
|
||||
pkt_io->polling_func(pkt_io->handle, thr_idx);
|
||||
}
|
||||
|
||||
struct packet_io_stat *packet_io_stat(struct packet_io *pkt_io, uint16_t thr_idx)
|
||||
{
|
||||
return pkt_io->stat_func(pkt_io->handle, thr_idx);
|
||||
|
||||
Reference in New Issue
Block a user