#include #include #include "packet_io.h" #include "packet_io_marsio.h" #include "packet_io_dumpfile.h" typedef void *new_cb(void *options); typedef void free_cb(void *handle); typedef void *stat_cb(void *handle); typedef int init_cb(void *handle, uint16_t thread_id); typedef int recv_cb(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); typedef void send_cb(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); struct packet_io { void *handle; new_cb *on_new; free_cb *on_free; stat_cb *on_stat; init_cb *on_init; recv_cb *on_recv; send_cb *on_send; }; struct packet_io *packet_io_new(struct packet_io_options *opts) { struct packet_io *handle = (struct packet_io *)calloc(1, sizeof(struct packet_io)); if (handle == NULL) { PACKET_IO_LOG_ERROR("unable to alloc packet io"); return NULL; } struct packet_io_marsio_opts marsio_opts; strncpy(marsio_opts.app_symbol, opts->app_symbol, sizeof(marsio_opts.app_symbol)); strncpy(marsio_opts.dev_symbol, opts->dev_symbol, sizeof(marsio_opts.dev_symbol)); memcpy(marsio_opts.cpu_mask, opts->cpu_mask, sizeof(marsio_opts.cpu_mask)); marsio_opts.nr_threads = opts->nr_threads; struct packet_io_dumpfile_opts dumpfile_opts; strncpy(dumpfile_opts.dumpfile_dir, opts->dumpfile_dir, sizeof(dumpfile_opts.dumpfile_dir)); dumpfile_opts.nr_threads = opts->nr_threads; void *_opts = NULL; if (opts->mode == PACKET_IO_MARSIO) { _opts = &marsio_opts; handle->on_new = (new_cb *)packet_io_marsio_new; handle->on_free = (free_cb *)packet_io_marsio_free; handle->on_stat = (stat_cb *)packet_io_marsio_stat; handle->on_init = (init_cb *)packet_io_marsio_init; handle->on_recv = (recv_cb *)packet_io_marsio_recv; handle->on_send = (send_cb *)packet_io_marsio_send; } else { _opts = &dumpfile_opts; handle->on_new = (new_cb *)packet_io_dumpfile_new; handle->on_free = (free_cb *)packet_io_dumpfile_free; handle->on_stat = (stat_cb *)packet_io_dumpfile_stat; handle->on_init = (init_cb *)packet_io_dumpfile_init; handle->on_recv = (recv_cb *)packet_io_dumpfile_recv; handle->on_send = (send_cb *)packet_io_dumpfile_send; } handle->handle = handle->on_new(_opts); if (handle->handle == NULL) { goto error_out; } return handle; error_out: packet_io_free(handle); return NULL; } void packet_io_free(struct packet_io *handle) { if (handle) { handle->on_free(handle->handle); free(handle); handle = NULL; } } void packet_io_print_stat(struct packet_io *handle) { struct packet_io_stat *stat = packet_io_get_stat(handle); PACKET_IO_LOG_DEBUG("rx_pkts : %lu, rx_bytes : %lu", stat->rx_pkts, stat->rx_bytes); PACKET_IO_LOG_DEBUG("tx_pkts : %lu, tx_bytes : %lu", stat->tx_pkts, stat->tx_bytes); PACKET_IO_LOG_DEBUG("drop_pkts : %lu, drop_bytes : %lu", stat->drop_pkts, stat->drop_bytes); PACKET_IO_LOG_DEBUG("inject_pkts : %lu, inject_bytes : %lu", stat->inject_pkts, stat->inject_bytes); PACKET_IO_LOG_DEBUG("keepalive_pkts : %lu, keepalive_bytes : %lu", stat->keepalive_pkts, stat->keepalive_bytes); } struct packet_io_stat *packet_io_get_stat(struct packet_io *handle) { return (struct packet_io_stat *)handle->on_stat(handle->handle); } int packet_io_init(struct packet_io *handle, uint16_t thread_id) { return handle->on_init(handle->handle, thread_id); } int packet_io_ingress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) { return handle->on_recv(handle->handle, thread_id, pkts, nr_pkts); } void packet_io_egress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) { handle->on_send(handle->handle, thread_id, pkts, nr_pkts); }