This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-stellar/infra/packet_io/packet_io.c

340 lines
9.4 KiB
C
Raw Normal View History

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "toml.h"
#include "pcap_io.h"
2024-04-10 17:50:51 +08:00
#include "marsio_io.h"
2024-09-19 16:23:12 +08:00
#include "log_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
{
2024-09-20 18:41:07 +08:00
struct packet_io_config *cfg;
void *handle;
void *(*new_func)(const struct packet_io_config *cfg);
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);
void (*yield_func)(void *handle, uint16_t thr_idx);
struct packet_io_stat *(*stat_func)(void *handle, uint16_t thr_idx);
};
2024-09-20 18:41:07 +08:00
static struct packet_io_config *packet_io_config_new(const char *toml_file)
{
int ret = -1;
const char *ptr;
char *ptr_mode = NULL;
2024-08-30 18:33:41 +08:00
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;
2024-09-20 18:41:07 +08:00
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");
2024-08-30 18:33:41 +08:00
if (ptr == NULL || toml_rtos(ptr, &ptr_pcap_path) != 0)
2024-04-10 17:50:51 +08:00
{
PACKET_IO_LOG_ERROR("config file missing packet_io.pcap_path");
goto error_out;
2024-04-10 17:50:51 +08:00
}
2024-08-30 18:33:41 +08:00
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)
2024-04-10 17:50:51 +08:00
{
PACKET_IO_LOG_ERROR("config file missing packet_io.app_symbol");
goto error_out;
2024-04-10 17:50:51 +08:00
}
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)
2024-05-15 11:40:00 +08:00
{
PACKET_IO_LOG_ERROR("config file missing packet_io.nr_worker_thread");
goto error_out;
2024-05-15 11:40:00 +08:00
}
cfg->nr_worker_thread = atoi(ptr);
if (cfg->nr_worker_thread == 0 || cfg->nr_worker_thread > MAX_THREAD_NUM)
2024-05-15 11:40:00 +08:00
{
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;
2024-05-15 11:40:00 +08:00
}
mask = toml_array_in(table, "cpu_mask");
if (mask == NULL)
2024-04-10 17:50:51 +08:00
{
PACKET_IO_LOG_ERROR("config file missing packet_io.cpu_mask");
goto error_out;
2024-04-10 17:50:51 +08:00
}
for (uint16_t i = 0; i < cfg->nr_worker_thread; i++)
2024-04-10 17:50:51 +08:00
{
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);
2024-04-10 17:50:51 +08:00
}
ptr = toml_raw_in(table, "idle_yield_interval_ms");
if (ptr == NULL)
2024-04-10 17:50:51 +08:00
{
PACKET_IO_LOG_ERROR("config file missing packet_io.idle_yield_interval_ms");
goto error_out;
2024-04-10 17:50:51 +08:00
}
cfg->idle_yield_interval_ms = atoll(ptr);
if (cfg->idle_yield_interval_ms > 60000)
2024-04-10 17:50:51 +08:00
{
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;
2024-04-10 17:50:51 +08:00
}
ret = 0;
error_out:
if (ptr_mode)
2024-04-10 17:50:51 +08:00
{
free(ptr_mode);
2024-04-10 17:50:51 +08:00
}
2024-08-30 18:33:41 +08:00
if (ptr_pcap_path)
{
2024-08-30 18:33:41 +08:00
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)
2024-04-10 17:50:51 +08:00
{
fclose(fp);
2024-04-10 17:50:51 +08:00
}
2024-09-20 18:41:07 +08:00
if (ret == -1)
2024-04-10 17:50:51 +08:00
{
2024-09-20 18:41:07 +08:00
free(cfg);
return NULL;
2024-04-10 17:50:51 +08:00
}
2024-09-20 18:41:07 +08:00
else
{
2024-09-20 18:41:07 +08:00
return cfg;
}
}
2024-09-20 18:41:07 +08:00
static void packet_io_config_free(struct packet_io_config *cfg)
{
if (cfg)
{
free(cfg);
cfg = NULL;
}
}
2024-09-20 18:41:07 +08:00
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);
}
}
2024-09-20 18:41:07 +08:00
struct packet_io *packet_io_new(const char *toml_file)
{
struct packet_io *pkt_io = (struct packet_io *)calloc(1, sizeof(struct packet_io));
if (pkt_io == NULL)
{
return NULL;
}
2024-09-20 18:41:07 +08:00
pkt_io->cfg = packet_io_config_new(toml_file);
if (pkt_io->cfg == NULL)
{
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;
}
else
{
pkt_io->new_func = pcap_io_new;
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->drop_func = pcap_io_drop;
pkt_io->yield_func = pcap_io_yield;
pkt_io->stat_func = pcap_io_stat;
}
2024-09-20 18:41:07 +08:00
pkt_io->handle = pkt_io->new_func(pkt_io->cfg);
if (pkt_io->handle == NULL)
{
packet_io_free(pkt_io);
return NULL;
}
return pkt_io;
}
void packet_io_free(struct packet_io *pkt_io)
{
if (pkt_io)
{
if (pkt_io->handle)
{
pkt_io->free_func(pkt_io->handle);
}
2024-09-20 18:41:07 +08:00
if (pkt_io->cfg)
{
packet_io_config_free(pkt_io->cfg);
}
free(pkt_io);
pkt_io = NULL;
}
}
int packet_io_isbreak(struct packet_io *pkt_io)
{
return pkt_io->isbreak_func(pkt_io->handle);
}
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)
{
return pkt_io->ingress_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)
{
pkt_io->egress_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)
{
pkt_io->drop_func(pkt_io->handle, thr_idx, pkts, nr_pkts);
}
void packet_io_yield(struct packet_io *pkt_io, uint16_t thr_idx)
{
pkt_io->yield_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);
}