Refactor Packet I/O
This commit is contained in:
243
src/packet_io/marsio_io.cpp
Normal file
243
src/packet_io/marsio_io.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <netinet/ether.h>
|
||||
|
||||
#include "stellar.h"
|
||||
#include "marsio.h"
|
||||
#include "packet_private.h"
|
||||
#include "marsio_io.h"
|
||||
|
||||
struct marsio_io
|
||||
{
|
||||
struct mr_instance *mr_ins;
|
||||
struct mr_vdev *mr_dev;
|
||||
struct mr_sendpath *mr_path;
|
||||
|
||||
struct packet_stat stat;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Private API
|
||||
******************************************************************************/
|
||||
|
||||
static int is_keepalive_packet(const char *data, int len)
|
||||
{
|
||||
if (data == NULL || len < (int)(sizeof(struct ethhdr)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ethhdr *eth_hdr = (struct ethhdr *)data;
|
||||
if (eth_hdr->h_proto == 0xAAAA)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
struct marsio_io *marsio_io_new(const char *app_symbol, const char *dev_symbol, uint16_t *cpu_mask, uint8_t nr_threads)
|
||||
{
|
||||
int opt = 1;
|
||||
cpu_set_t coremask;
|
||||
CPU_ZERO(&coremask);
|
||||
for (uint8_t i = 0; i < nr_threads; i++)
|
||||
{
|
||||
CPU_SET(cpu_mask[i], &coremask);
|
||||
}
|
||||
|
||||
struct marsio_io *handle = (struct marsio_io *)calloc(1, sizeof(struct marsio_io));
|
||||
if (handle == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to allocate memory for marsio_io");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle->mr_ins = marsio_create();
|
||||
if (handle->mr_ins == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to create marsio instance");
|
||||
goto error_out;
|
||||
}
|
||||
marsio_option_set(handle->mr_ins, MARSIO_OPT_THREAD_MASK_IN_CPUSET, &coremask, sizeof(cpu_set_t));
|
||||
marsio_option_set(handle->mr_ins, MARSIO_OPT_EXIT_WHEN_ERR, &opt, sizeof(opt));
|
||||
if (marsio_init(handle->mr_ins, app_symbol) != 0)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to init marsio instance");
|
||||
goto error_out;
|
||||
}
|
||||
handle->mr_dev = marsio_open_device(handle->mr_ins, dev_symbol, nr_threads, nr_threads);
|
||||
if (handle->mr_dev == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to open marsio device");
|
||||
goto error_out;
|
||||
}
|
||||
handle->mr_path = marsio_sendpath_create_by_vdev(handle->mr_dev);
|
||||
if (handle->mr_path == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to create marsio sendpath");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
return handle;
|
||||
|
||||
error_out:
|
||||
marsio_io_free(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void marsio_io_free(struct marsio_io *handle)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
if (handle->mr_path)
|
||||
{
|
||||
marsio_sendpath_destory(handle->mr_path);
|
||||
handle->mr_path = NULL;
|
||||
}
|
||||
if (handle->mr_dev)
|
||||
{
|
||||
marsio_close_device(handle->mr_dev);
|
||||
handle->mr_dev = NULL;
|
||||
}
|
||||
if (handle->mr_ins)
|
||||
{
|
||||
marsio_destory(handle->mr_ins);
|
||||
handle->mr_ins = NULL;
|
||||
}
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct packet_stat *marsio_io_stat(struct marsio_io *handle)
|
||||
{
|
||||
return &handle->stat;
|
||||
}
|
||||
|
||||
int marsio_io_init(struct marsio_io *handle, uint16_t thr_idx)
|
||||
{
|
||||
if (marsio_thread_init(handle->mr_ins) != 0)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to init marsio thread");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int marsio_io_ingress(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
|
||||
{
|
||||
struct packet *pkt;
|
||||
marsio_buff_t *mbuff;
|
||||
marsio_buff_t *rx_buffs[RX_BURST_MAX];
|
||||
int nr_recv;
|
||||
int nr_parsed = 0;
|
||||
int len;
|
||||
char *data;
|
||||
|
||||
nr_recv = marsio_recv_burst(handle->mr_dev, thr_idx, rx_buffs, MIN(RX_BURST_MAX, nr_pkts));
|
||||
if (nr_recv <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nr_recv; i++)
|
||||
{
|
||||
mbuff = rx_buffs[i];
|
||||
data = marsio_buff_mtod(mbuff);
|
||||
len = marsio_buff_datalen(mbuff);
|
||||
|
||||
ATOMIC_ADD(&handle->stat.dev_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_rx_bytes, len);
|
||||
|
||||
if (is_keepalive_packet(data, len))
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.keep_alive_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.keep_alive_bytes, len);
|
||||
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_bytes, len);
|
||||
|
||||
marsio_send_burst(handle->mr_path, thr_idx, &mbuff, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marsio_buff_is_ctrlbuf(mbuff))
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.ctrl_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.ctrl_rx_bytes, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.raw_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.raw_rx_bytes, len);
|
||||
}
|
||||
|
||||
pkt = &pkts[nr_parsed];
|
||||
packet_parse(pkt, data, len);
|
||||
packet_set_io_ctx(pkt, mbuff);
|
||||
packet_set_action(pkt, PACKET_ACTION_FORWARD);
|
||||
nr_parsed++;
|
||||
}
|
||||
|
||||
return nr_parsed;
|
||||
}
|
||||
|
||||
void marsio_io_egress(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
|
||||
{
|
||||
struct packet *pkt;
|
||||
marsio_buff_t *mbuff;
|
||||
int len;
|
||||
|
||||
for (int i = 0; i < nr_pkts; i++)
|
||||
{
|
||||
pkt = &pkts[i];
|
||||
len = packet_get_len(pkt);
|
||||
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_bytes, len);
|
||||
|
||||
mbuff = (marsio_buff_t *)packet_get_io_ctx(pkt);
|
||||
assert(mbuff != NULL);
|
||||
|
||||
if (marsio_buff_is_ctrlbuf(mbuff))
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.ctrl_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.ctrl_tx_bytes, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.raw_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.raw_tx_bytes, len);
|
||||
}
|
||||
|
||||
marsio_send_burst(handle->mr_path, thr_idx, &mbuff, 1);
|
||||
packet_free(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
void marsio_io_drop(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
|
||||
{
|
||||
struct packet *pkt;
|
||||
marsio_buff_t *mbuff;
|
||||
|
||||
for (int i = 0; i < nr_pkts; i++)
|
||||
{
|
||||
pkt = &pkts[i];
|
||||
mbuff = (marsio_buff_t *)packet_get_io_ctx(pkt);
|
||||
if (mbuff)
|
||||
{
|
||||
marsio_buff_free(handle->mr_ins, &mbuff, 1, 0, thr_idx);
|
||||
}
|
||||
packet_free(pkt);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user