#include #include #include #include #include "marsio.h" struct mr_instance { marsio_buff_t *current_recv_mbuff_ptr; marsio_buff_t *current_send_mbuff_ptr; }; struct mr_vdev { struct mr_instance *mr_instance; }; struct mr_sendpath { struct mr_instance *mr_instance; }; struct mrb_metadata_route_ctx { uint8_t dir; uint8_t link_id; uint16_t port_ingress; uint16_t port_egress; uint16_t link_db_index; uint32_t hash_usr; }; struct mrb_metadata { uint8_t dir : 1; uint8_t packet_create_from_nf : 1; uint8_t link_id : 6; uint8_t is_ctrlbuf : 1; uint8_t un_used : 7; uint16_t payload_offset; uint64_t session_id; uint8_t start_sid; uint8_t nr_sid; uint16_t cur_sid; uint16_t sids[8]; uint16_t port_ingress; uint16_t port_egress; uint16_t link_db_index; }; struct mock_marsio_buff_t { struct mrb_metadata metadata; char *raw_data; int raw_len; int buff_size; char *buff_start; } __attribute__((__packed__)); struct mr_instance *marsio_create() { struct mr_instance *instance = (struct mr_instance *)calloc(1, sizeof(struct mr_instance)); instance->current_recv_mbuff_ptr = NULL; instance->current_send_mbuff_ptr = NULL; return instance; } int marsio_destory(struct mr_instance *instance) { if (instance) { free(instance); instance = NULL; } return 0; } struct mr_vdev *marsio_open_device(struct mr_instance *instance, const char *devsym, unsigned int nr_rxstream, unsigned int nr_txstream) { struct mr_vdev *vdev = (struct mr_vdev *)calloc(1, sizeof(struct mr_vdev)); vdev->mr_instance = instance; return vdev; } void marsio_close_device(struct mr_vdev *vdev) { if (vdev) { free(vdev); vdev = NULL; } } void marsio_get_device_ether_addr(struct mr_vdev *vdev, void *str_ether_addr, uint8_t size) { } struct mr_sendpath *marsio_sendpath_create_by_vdev(struct mr_vdev *dest_device) { struct mr_sendpath *sendpath = (struct mr_sendpath *)calloc(1, sizeof(struct mr_sendpath)); sendpath->mr_instance = dest_device->mr_instance; return sendpath; } void marsio_sendpath_destory(struct mr_sendpath *sendpath) { if (sendpath) { free(sendpath); sendpath = NULL; } } int marsio_init(struct mr_instance *instance, const char *appsym) { return 0; } int marsio_option_set(struct mr_instance *instance, marsio_opt_type_t opt_type, void *opt, size_t sz_opt) { return 0; } int marsio_thread_init(struct mr_instance *instance) { return 0; } int marsio_poll_wait(struct mr_instance *instance, struct mr_vdev *vdevs[], unsigned int nr_vdevs, unsigned int tid, int timeout) { return 0; } int marsio_buff_set_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; struct mrb_metadata *mrb_metadata = &mbuf->metadata; struct mrb_metadata_route_ctx *route_ctx = NULL; switch (type) { case MR_BUFF_ROUTE_CTX: route_ctx = (struct mrb_metadata_route_ctx *)data; assert(route_ctx != NULL); mrb_metadata->packet_create_from_nf = 1; mrb_metadata->dir = route_ctx->dir; mrb_metadata->port_ingress = route_ctx->port_ingress; mrb_metadata->port_egress = route_ctx->port_egress; mrb_metadata->link_db_index = route_ctx->link_db_index; mrb_metadata->link_id = route_ctx->link_id; return 0; case MR_BUFF_SESSION_ID: mrb_metadata->session_id = *(uint64_t *)data; return 0; case MR_BUFF_PAYLOAD_OFFSET: mrb_metadata->payload_offset = *(uint16_t *)data; return 0; default: return -1; } return 0; } int marsio_buff_get_metadata(marsio_buff_t *m, enum mr_buff_metadata_type type, void *data, unsigned int sz_data) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; struct mrb_metadata *mrb_metadata = &mbuf->metadata; struct mrb_metadata_route_ctx *route_ctx = NULL; switch (type) { case MR_BUFF_ROUTE_CTX: if (sz_data < sizeof(struct mrb_metadata_route_ctx)) { return -1; } route_ctx = (struct mrb_metadata_route_ctx *)data; if (route_ctx != NULL) { route_ctx->dir = mrb_metadata->dir; route_ctx->port_ingress = mrb_metadata->port_ingress; route_ctx->port_egress = mrb_metadata->port_egress; route_ctx->link_db_index = mrb_metadata->link_db_index; route_ctx->link_id = mrb_metadata->link_id; route_ctx->hash_usr = 0; } return sizeof(struct mrb_metadata_route_ctx); case MR_BUFF_DIR: if (sz_data < sizeof(unsigned int)) { return -1; } *(unsigned int *)(data) = (unsigned int)mrb_metadata->dir; return sizeof(unsigned int); case MR_BUFF_SESSION_ID: if (sz_data < sizeof(uint64_t)) { return -1; } *(uint64_t *)(data) = (uint64_t)mrb_metadata->session_id; return sizeof(uint64_t); case MR_BUFF_PAYLOAD_OFFSET: if (sz_data < sizeof(uint16_t)) { return -1; } *(uint16_t *)(data) = (uint16_t)mrb_metadata->payload_offset; return sizeof(uint16_t); default: return -1; } return 0; } int marsio_buff_set_sid_list(marsio_buff_t *m, sid_t *slist, uint8_t sz_slist) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; struct mrb_metadata *mrb_metadata = &mbuf->metadata; if (sz_slist > sizeof(mrb_metadata->sids) / sizeof(mrb_metadata->sids[0])) { return -1; } for (uint8_t i = 0; i < sz_slist; i++) { mrb_metadata->sids[i] = slist[i]; } mrb_metadata->start_sid = 0; mrb_metadata->nr_sid = sz_slist; return 0; } int marsio_buff_get_sid_list(marsio_buff_t *m, sid_t *out_slist, uint8_t sz_out_slist) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; struct mrb_metadata *mrb_metadata = &mbuf->metadata; uint8_t out_i = 0; for (uint8_t i = mrb_metadata->start_sid; i < mrb_metadata->start_sid + mrb_metadata->nr_sid && out_i < sz_out_slist; i++, out_i++) { out_slist[out_i] = mrb_metadata->sids[i]; } return out_i; } int marsio_buff_malloc_global(struct mr_instance *instance, marsio_buff_t *marsio_buff[], unsigned int nr_mbufs, int socket_id, int thread_id) { for (unsigned int i = 0; i < nr_mbufs; i++) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)calloc(1, sizeof(struct mock_marsio_buff_t) + 4096); mbuf->buff_size = 4096; mbuf->buff_start = (char *)mbuf + sizeof(struct mock_marsio_buff_t); mbuf->raw_data = mbuf->buff_start + 50; marsio_buff[i] = mbuf; } return nr_mbufs; } void marsio_buff_free(struct mr_instance *instance, marsio_buff_t *marsio_buff[], unsigned int nr_mbufs, int socket_id, int thread_id) { for (unsigned int i = 0; i < nr_mbufs; i++) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)marsio_buff[i]; if (mbuf == instance->current_recv_mbuff_ptr) { instance->current_recv_mbuff_ptr = NULL; } if (mbuf == instance->current_send_mbuff_ptr) { instance->current_send_mbuff_ptr = NULL; } if (mbuf) { memset(mbuf, 0, sizeof(struct mock_marsio_buff_t)); free(mbuf); mbuf = NULL; } } } char *marsio_buff_mtod(marsio_buff_t *m) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; return mbuf->raw_data; } uint32_t marsio_buff_datalen(marsio_buff_t *m) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; return mbuf->raw_len; } char *marsio_buff_adj(marsio_buff_t *m, uint16_t len) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; mbuf->raw_data += len; return mbuf->raw_data; } char *marsio_buff_append(marsio_buff_t *m, uint16_t len) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; mbuf->raw_len += len; return mbuf->raw_data; } char *marsio_buff_prepend(marsio_buff_t *m, uint16_t len) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; mbuf->raw_len += len; mbuf->raw_data -= len; return mbuf->raw_data; } void marsio_buff_ctrlzone_reset(marsio_buff_t *m) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; struct mrb_metadata *mrb_metadata = &mbuf->metadata; memset(mrb_metadata, 0, sizeof(struct mrb_metadata)); } int marsio_buff_is_ctrlbuf(marsio_buff_t *m) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; struct mrb_metadata *mrb_metadata = &mbuf->metadata; return mrb_metadata->is_ctrlbuf; } void marsio_buff_set_ctrlbuf(marsio_buff_t *m) { struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)m; struct mrb_metadata *mrb_metadata = &mbuf->metadata; mrb_metadata->is_ctrlbuf = 1; } int marsio_recv_burst(struct mr_vdev *vdev, queue_id_t qid, marsio_buff_t *mbufs[], int nr_mbufs) { mbufs[0] = vdev->mr_instance->current_recv_mbuff_ptr; return 1; } int marsio_send_burst(struct mr_sendpath *sendpath, queue_id_t qid, marsio_buff_t *mbufs[], int nr_mbufs) { assert(nr_mbufs == 1); sendpath->mr_instance->current_send_mbuff_ptr = mbufs[0]; return marsio_buff_datalen(mbufs[0]); } // new add, only for gtest void marsio_set_recv_mbuff(struct mr_instance *instance, marsio_buff_t *mbuff) { instance->current_recv_mbuff_ptr = mbuff; } void marsio_set_send_mbuff(struct mr_instance *instance, marsio_buff_t *mbuff) { instance->current_send_mbuff_ptr = mbuff; } marsio_buff_t *marsio_get_recv_mbuff(struct mr_instance *instance) { return instance->current_recv_mbuff_ptr; } marsio_buff_t *marsio_get_send_mbuff(struct mr_instance *instance) { return instance->current_send_mbuff_ptr; } int marsio_mbuff_cmp(marsio_buff_t *mbuff1, marsio_buff_t *mbuff2) { struct mock_marsio_buff_t *mbuf1 = (struct mock_marsio_buff_t *)mbuff1; struct mock_marsio_buff_t *mbuf2 = (struct mock_marsio_buff_t *)mbuff2; if (mbuf1 == mbuf2) { return 0; } if (mbuf1 && mbuf2) { if (memcmp(&mbuf1->metadata, &mbuf2->metadata, sizeof(struct mrb_metadata)) != 0) { return 1; } if (mbuf1->raw_len != mbuf2->raw_len) { return 1; } if (memcmp(mbuf1->raw_data, mbuf2->raw_data, mbuf2->raw_len) != 0) { return 1; } else { return 0; } } else { return 1; } } marsio_buff_t *marsio_mbuff_dup(marsio_buff_t *m) { struct mock_marsio_buff_t *orig = (struct mock_marsio_buff_t *)m; struct mock_marsio_buff_t *mbuf = (struct mock_marsio_buff_t *)calloc(1, sizeof(struct mock_marsio_buff_t) + 4096); mbuf->buff_size = 4096; mbuf->buff_start = (char *)mbuf + sizeof(struct mock_marsio_buff_t); mbuf->raw_data = mbuf->buff_start + 50; memcpy(&mbuf->metadata, &orig->metadata, sizeof(struct mrb_metadata)); memcpy(mbuf->raw_data, orig->raw_data, orig->raw_len); mbuf->raw_len = orig->raw_len; return mbuf; }