@@ -209,6 +209,17 @@ void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset);
*/
void odp_packet_print(odp_packet_t pkt);
+/**
+ * Copy contents and metadata from pkt_src to pkt_dst
+ * Useful when creating copies of packets
+ *
+ * @param pkt_dst Destination packet
+ * @param pkt_src Source packet
+ *
+ * @return 0 if successful
+ */
+int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src);
+
#ifdef __cplusplus
}
#endif
@@ -107,6 +107,8 @@ typedef struct odp_buffer_chunk_hdr_t {
int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf);
+void odp_buffer_copy_scatter(odp_buffer_t buf_dst, odp_buffer_t buf_src);
+
#ifdef __cplusplus
}
@@ -111,3 +111,9 @@ void odp_buffer_print(odp_buffer_t buf)
printf("\n%s\n", str);
}
+
+void odp_buffer_copy_scatter(odp_buffer_t buf_dst, odp_buffer_t buf_src)
+{
+ (void)buf_dst;
+ (void)buf_src;
+}
@@ -328,3 +328,41 @@ void odp_packet_print(odp_packet_t pkt)
printf("\n%s\n", str);
}
+
+int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src)
+{
+ odp_packet_hdr_t *const pkt_hdr_dst = odp_packet_hdr(pkt_dst);
+ odp_packet_hdr_t *const pkt_hdr_src = odp_packet_hdr(pkt_src);
+ const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
+ uint8_t *start_src;
+ uint8_t *start_dst;
+ size_t len;
+
+ if (pkt_dst == ODP_PACKET_INVALID || pkt_src == ODP_PACKET_INVALID)
+ return -1;
+
+ if (pkt_hdr_dst->buf_hdr.size <
+ pkt_hdr_src->frame_len + pkt_hdr_src->frame_offset)
+ return -1;
+
+ /* Copy packet header */
+ start_dst = (uint8_t *)pkt_hdr_dst + start_offset;
+ start_src = (uint8_t *)pkt_hdr_src + start_offset;
+ len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
+ memcpy(start_dst, start_src, len);
+
+ /* Copy frame payload */
+ start_dst = (uint8_t *)odp_packet_start(pkt_dst);
+ start_src = (uint8_t *)odp_packet_start(pkt_src);
+ len = pkt_hdr_src->frame_len;
+ memcpy(start_dst, start_src, len);
+
+ /* Copy useful things from the buffer header */
+ pkt_hdr_dst->buf_hdr.cur_offset = pkt_hdr_src->buf_hdr.cur_offset;
+
+ /* Create a copy of the scatter list */
+ odp_buffer_copy_scatter(odp_buffer_from_packet(pkt_dst),
+ odp_buffer_from_packet(pkt_src));
+
+ return 0;
+}
@@ -25,6 +25,7 @@
#include <helper/odp_linux.h>
#include <helper/odp_eth.h>
#include <helper/odp_ip.h>
+#include <helper/odp_packet_helper.h>
#include <odp_pktio_netmap.h>
@@ -149,33 +150,25 @@ static void *pktio_queue_thread(void *arg)
/* Lookup the thread associated with the entry */
pktio_nr = args->pktio_tbl[pktio_tmp];
- odp_queue_enq(args->thread[pktio_nr].bridge_q, buf);
/* Send back packets arrived on physical interface */
if (args->thread[pktio_nr].netmap_mode == ODP_NETMAP_MODE_HW) {
odp_packet_t pkt_copy;
- odp_buffer_t buf_copy;
- size_t frame_len = odp_packet_get_len(pkt);
- size_t l2_offset = odp_packet_l2_offset(pkt);
- size_t l3_offset = odp_packet_l3_offset(pkt);
-
- buf_copy = odp_buffer_alloc(pkt_pool);
- pkt_copy = odp_packet_from_buffer(buf_copy);
-
- odp_packet_init(pkt_copy);
- odp_packet_set_len(pkt_copy, frame_len);
- odp_packet_set_l2_offset(pkt_copy, l2_offset);
- odp_packet_set_l3_offset(pkt_copy, l3_offset);
-
- memcpy(odp_buffer_addr(pkt_copy),
- odp_buffer_addr(pkt), frame_len);
- swap_pkt_addrs(&pkt_copy, 1);
+ pkt_copy = odp_packet_alloc(pkt_pool);
- buf_copy = odp_buffer_from_packet(pkt_copy);
- odp_queue_enq(outq_def, buf_copy);
+ if (odp_packet_copy(pkt_copy, pkt) != 0) {
+ ODP_ERR("Packet copy failed!\n");
+ odp_packet_free(pkt_copy);
+ } else {
+ swap_pkt_addrs(&pkt_copy, 1);
+ odp_queue_enq(outq_def,
+ odp_buffer_from_packet(pkt_copy));
+ }
}
+ odp_queue_enq(args->thread[pktio_nr].bridge_q, buf);
+
/* Print packet counts every once in a while */
if (odp_unlikely(pkt_cnt++ % 100000 == 0)) {
printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt);
This function will not some more work when the scatter/gather support is added, for now the odp_buffer_copy_scatter is just a stub. Signed-off-by: Ciprian Barbu <ciprian.barbu@linaro.org> --- include/odp_packet.h | 11 +++++++ .../linux-generic/include/odp_buffer_internal.h | 2 ++ platform/linux-generic/source/odp_buffer.c | 6 ++++ platform/linux-generic/source/odp_packet.c | 38 ++++++++++++++++++++++ test/packet_netmap/odp_example_pktio_netmap.c | 31 +++++++----------- 5 files changed, 69 insertions(+), 19 deletions(-)