rofl_result_t pop_datapacket_offset(datapacket_dpdk_t *dpkt, unsigned int offset, unsigned int num_of_bytes){ uint8_t *src_ptr = get_buffer_dpdk(dpkt); uint8_t *dst_ptr = (uint8_t*)rte_pktmbuf_adj(dpkt->mbuf, num_of_bytes); //NOTE dst_ptr = src_ptr + num_of_bytes if( NULL==dst_ptr ) return ROFL_FAILURE; if(false==rte_pktmbuf_is_contiguous(dpkt->mbuf)){ assert(0); return ROFL_FAILURE; } // move first bytes backward memmove(dst_ptr, src_ptr, offset); #ifndef NDEBUG // set now unused bytes to 0x00 for easier debugging memset(src_ptr, 0x00, num_of_bytes); #endif dpkt->clas_state.base = get_buffer_dpdk(dpkt); dpkt->clas_state.len = get_buffer_length_dpdk(dpkt); return ROFL_SUCCESS; }
/* * Push&pop operations */ rofl_result_t push_datapacket_offset(datapacket_dpdk_t *dpkt, unsigned int offset, unsigned int num_of_bytes){ uint8_t *src_ptr = get_buffer_dpdk(dpkt); uint8_t *dst_ptr = (uint8_t*)rte_pktmbuf_prepend(dpkt->mbuf, num_of_bytes); //NOTE dst_ptr = src_ptr - num_of_bytes if( NULL==dst_ptr ) return ROFL_FAILURE; if(false==rte_pktmbuf_is_contiguous(dpkt->mbuf)){ assert(0); return ROFL_FAILURE; } // move header num_of_bytes backward memmove(dst_ptr, src_ptr, offset); #ifndef NDEBUG // initialize new pushed memory area with 0x00 memset(dst_ptr + offset, 0x00, num_of_bytes); #endif dpkt->clas_state.base = get_buffer_dpdk(dpkt); dpkt->clas_state.len = get_buffer_length_dpdk(dpkt); return ROFL_SUCCESS; }
/* * test data manipulation in mbuf with non-ascii data */ static int test_pktmbuf_with_non_ascii_data(void) { struct rte_mbuf *m = NULL; char *data; m = rte_pktmbuf_alloc(pktmbuf_pool); if (m == NULL) GOTO_FAIL("Cannot allocate mbuf"); if (rte_pktmbuf_pkt_len(m) != 0) GOTO_FAIL("Bad length"); data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN); if (data == NULL) GOTO_FAIL("Cannot append data"); if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad pkt length"); if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad data length"); memset(data, 0xff, rte_pktmbuf_pkt_len(m)); if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); rte_pktmbuf_dump(m, MBUF_TEST_DATA_LEN); rte_pktmbuf_free(m); return 0; fail: if(m) { rte_pktmbuf_free(m); } return -1; }
rofl_result_t pop_datapacket_point(datapacket_dpdk_t *dpkt, uint8_t* pop_point, unsigned int num_of_bytes){ uint8_t *src_ptr = get_buffer_dpdk(dpkt); if(false==rte_pktmbuf_is_contiguous(dpkt->mbuf)){ assert(0); return ROFL_FAILURE; } if (pop_point < src_ptr){ return ROFL_FAILURE; } if (((uint8_t*)pop_point + num_of_bytes) > (src_ptr + get_buffer_length_dpdk(dpkt))){ return ROFL_FAILURE; } size_t offset = (src_ptr - pop_point); return pop_datapacket_offset(dpkt, offset, num_of_bytes); }
/* * test data manipulation in mbuf */ static int test_one_pktmbuf(void) { struct rte_mbuf *m = NULL; char *data, *data2, *hdr; unsigned i; printf("Test pktmbuf API\n"); /* alloc a mbuf */ m = rte_pktmbuf_alloc(pktmbuf_pool); if (m == NULL) GOTO_FAIL("Cannot allocate mbuf"); if (rte_pktmbuf_pkt_len(m) != 0) GOTO_FAIL("Bad length"); rte_pktmbuf_dump(m, 0); /* append data */ data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN); if (data == NULL) GOTO_FAIL("Cannot append data"); if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad pkt length"); if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad data length"); memset(data, 0x66, rte_pktmbuf_pkt_len(m)); if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); rte_pktmbuf_dump(m, MBUF_TEST_DATA_LEN); rte_pktmbuf_dump(m, 2*MBUF_TEST_DATA_LEN); /* this append should fail */ data2 = rte_pktmbuf_append(m, (uint16_t)(rte_pktmbuf_tailroom(m) + 1)); if (data2 != NULL) GOTO_FAIL("Append should not succeed"); /* append some more data */ data2 = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2); if (data2 == NULL) GOTO_FAIL("Cannot append data"); if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2) GOTO_FAIL("Bad pkt length"); if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2) GOTO_FAIL("Bad data length"); if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); /* trim data at the end of mbuf */ if (rte_pktmbuf_trim(m, MBUF_TEST_DATA_LEN2) < 0) GOTO_FAIL("Cannot trim data"); if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad pkt length"); if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad data length"); if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); /* this trim should fail */ if (rte_pktmbuf_trim(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) == 0) GOTO_FAIL("trim should not succeed"); /* prepend one header */ hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR1_LEN); if (hdr == NULL) GOTO_FAIL("Cannot prepend"); if (data - hdr != MBUF_TEST_HDR1_LEN) GOTO_FAIL("Prepend failed"); if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN) GOTO_FAIL("Bad pkt length"); if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN) GOTO_FAIL("Bad data length"); if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); memset(hdr, 0x55, MBUF_TEST_HDR1_LEN); /* prepend another header */ hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR2_LEN); if (hdr == NULL) GOTO_FAIL("Cannot prepend"); if (data - hdr != MBUF_TEST_ALL_HDRS_LEN) GOTO_FAIL("Prepend failed"); if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN) GOTO_FAIL("Bad pkt length"); if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN) GOTO_FAIL("Bad data length"); if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); memset(hdr, 0x55, MBUF_TEST_HDR2_LEN); rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 1); rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 0); rte_pktmbuf_dump(m, 0); /* this prepend should fail */ hdr = rte_pktmbuf_prepend(m, (uint16_t)(rte_pktmbuf_headroom(m) + 1)); if (hdr != NULL) GOTO_FAIL("prepend should not succeed"); /* remove data at beginning of mbuf (adj) */ if (data != rte_pktmbuf_adj(m, MBUF_TEST_ALL_HDRS_LEN)) GOTO_FAIL("rte_pktmbuf_adj failed"); if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad pkt length"); if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) GOTO_FAIL("Bad data length"); if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); /* this adj should fail */ if (rte_pktmbuf_adj(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) != NULL) GOTO_FAIL("rte_pktmbuf_adj should not succeed"); /* check data */ if (!rte_pktmbuf_is_contiguous(m)) GOTO_FAIL("Buffer should be continuous"); for (i=0; i<MBUF_TEST_DATA_LEN; i++) { if (data[i] != 0x66) GOTO_FAIL("Data corrupted at offset %u", i); } /* free mbuf */ rte_pktmbuf_free(m); m = NULL; return 0; fail: if (m) rte_pktmbuf_free(m); return -1; }
/** * Process a crypto operation and complete a JOB_AES_HMAC job structure for * submission to the multi buffer library for processing. * * @param qp queue pair * @param op symmetric crypto operation * @param session GCM session * * @return * */ static int process_gcm_crypto_op(struct rte_crypto_sym_op *op, struct aesni_gcm_session *session) { uint8_t *src, *dst; struct rte_mbuf *m_src = op->m_src; uint32_t offset = op->cipher.data.offset; uint32_t part_len, total_len, data_len; RTE_ASSERT(m_src != NULL); while (offset >= m_src->data_len) { offset -= m_src->data_len; m_src = m_src->next; RTE_ASSERT(m_src != NULL); } data_len = m_src->data_len - offset; part_len = (data_len < op->cipher.data.length) ? data_len : op->cipher.data.length; /* Destination buffer is required when segmented source buffer */ RTE_ASSERT((part_len == op->cipher.data.length) || ((part_len != op->cipher.data.length) && (op->m_dst != NULL))); /* Segmented destination buffer is not supported */ RTE_ASSERT((op->m_dst == NULL) || ((op->m_dst != NULL) && rte_pktmbuf_is_contiguous(op->m_dst))); dst = op->m_dst ? rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *, op->cipher.data.offset) : rte_pktmbuf_mtod_offset(op->m_src, uint8_t *, op->cipher.data.offset); src = rte_pktmbuf_mtod_offset(m_src, uint8_t *, offset); /* sanity checks */ if (op->cipher.iv.length != 16 && op->cipher.iv.length != 12 && op->cipher.iv.length != 0) { GCM_LOG_ERR("iv"); return -1; } /* * GCM working in 12B IV mode => 16B pre-counter block we need * to set BE LSB to 1, driver expects that 16B is allocated */ if (op->cipher.iv.length == 12) { uint32_t *iv_padd = (uint32_t *)&op->cipher.iv.data[12]; *iv_padd = rte_bswap32(1); } if (op->auth.digest.length != 16 && op->auth.digest.length != 12 && op->auth.digest.length != 8) { GCM_LOG_ERR("digest"); return -1; } if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) { aesni_gcm_enc[session->key].init(&session->gdata, op->cipher.iv.data, op->auth.aad.data, (uint64_t)op->auth.aad.length); aesni_gcm_enc[session->key].update(&session->gdata, dst, src, (uint64_t)part_len); total_len = op->cipher.data.length - part_len; while (total_len) { dst += part_len; m_src = m_src->next; RTE_ASSERT(m_src != NULL); src = rte_pktmbuf_mtod(m_src, uint8_t *); part_len = (m_src->data_len < total_len) ? m_src->data_len : total_len; aesni_gcm_enc[session->key].update(&session->gdata, dst, src, (uint64_t)part_len); total_len -= part_len; } aesni_gcm_enc[session->key].finalize(&session->gdata, op->auth.digest.data, (uint64_t)op->auth.digest.length); } else { /* session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION */