1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation
12 #include <rte_common.h>
14 #include <rte_hexdump.h>
16 #include "rte_swx_port_source_sink.h"
18 #define CHECK(condition) \
29 #define TRACE(...) printf(__VA_ARGS__)
41 struct rte_mempool *pool;
43 struct rte_swx_port_in_stats stats;
44 struct rte_mbuf **pkts;
50 source_free(void *port)
52 struct source *p = port;
58 for (i = 0; i < p->n_pkts; i++)
59 rte_pktmbuf_free(p->pkts[i]);
67 source_create(void *args)
69 char pcap_errbuf[PCAP_ERRBUF_SIZE];
70 struct rte_swx_port_source_params *params = args;
71 struct source *p = NULL;
73 uint32_t n_pkts_max, i;
75 /* Check input arguments. */
78 CHECK(params->file_name && params->file_name[0]);
79 n_pkts_max = params->n_pkts_max ?
81 RTE_SWX_PORT_SOURCE_PKTS_MAX;
83 /* Resource allocation. */
84 f = pcap_open_offline(params->file_name, pcap_errbuf);
88 p = calloc(1, sizeof(struct source));
92 p->pkts = calloc(n_pkts_max, sizeof(struct rte_mbuf *));
97 p->params.pool = params->pool;
100 for (i = 0; i < n_pkts_max; i++) {
101 struct pcap_pkthdr pcap_pkthdr;
102 const uint8_t *pcap_pktdata;
106 /* Read new packet from PCAP file. */
107 pcap_pktdata = pcap_next(f, &pcap_pkthdr);
111 /* Allocate new buffer from pool. */
112 m = rte_pktmbuf_alloc(params->pool);
115 m_data = rte_pktmbuf_mtod(m, uint8_t *);
117 rte_memcpy(m_data, pcap_pktdata, pcap_pkthdr.caplen);
118 m->data_len = pcap_pkthdr.caplen;
119 m->pkt_len = pcap_pkthdr.caplen;
121 p->pkts[p->n_pkts] = m;
139 source_pkt_rx(void *port, struct rte_swx_pkt *pkt)
141 struct source *p = port;
142 struct rte_mbuf *m_dst, *m_src;
143 uint8_t *m_dst_data, *m_src_data;
145 /* m_src identification. */
146 m_src = p->pkts[p->pos];
147 m_src_data = rte_pktmbuf_mtod(m_src, uint8_t *);
149 /* m_dst allocation from pool. */
150 m_dst = rte_pktmbuf_alloc(p->params.pool);
154 /* m_dst initialization. */
155 m_dst->data_len = m_src->data_len;
156 m_dst->pkt_len = m_src->pkt_len;
157 m_dst->data_off = m_src->data_off;
159 m_dst_data = rte_pktmbuf_mtod(m_dst, uint8_t *);
160 rte_memcpy(m_dst_data, m_src_data, m_src->data_len);
162 /* pkt initialization. */
164 pkt->pkt = m_dst->buf_addr;
165 pkt->offset = m_dst->data_off;
166 pkt->length = m_dst->pkt_len;
168 TRACE("[Source port] Pkt RX (%u bytes at offset %u)\n",
172 rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
174 /* port stats update. */
176 p->stats.n_bytes += pkt->length;
180 if (p->pos == p->n_pkts)
187 source_stats_read(void *port, struct rte_swx_port_in_stats *stats)
189 struct source *p = port;
194 memcpy(stats, &p->stats, sizeof(p->stats));
197 struct rte_swx_port_in_ops rte_swx_port_source_ops = {
198 .create = source_create,
200 .pkt_rx = source_pkt_rx,
201 .stats_read = source_stats_read,
206 struct rte_swx_port_in_ops rte_swx_port_source_ops = {
219 struct rte_swx_port_out_stats stats;
223 pcap_dumper_t *f_dump;
228 sink_free(void *port)
230 struct sink *p = port;
237 pcap_dump_close(p->f_dump);
239 pcap_close(p->f_pcap);
246 sink_create(void *args __rte_unused)
250 /* Memory allocation. */
251 p = calloc(1, sizeof(struct sink));
257 struct rte_swx_port_sink_params *params = args;
259 if (params->file_name && params->file_name[0]) {
260 p->f_pcap = pcap_open_dead(DLT_EN10MB, 65535);
264 p->f_dump = pcap_dump_open(p->f_pcap,
280 sink_pkt_tx(void *port, struct rte_swx_pkt *pkt)
282 struct sink *p = port;
283 struct rte_mbuf *m = pkt->handle;
285 TRACE("[Sink port] Pkt TX (%u bytes at offset %u)\n",
289 rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
291 m->pkt_len = pkt->length;
292 m->data_len = (uint16_t)pkt->length;
293 m->data_off = (uint16_t)pkt->offset;
296 p->stats.n_bytes += pkt->length;
300 struct pcap_pkthdr pcap_pkthdr;
301 uint8_t *m_data = rte_pktmbuf_mtod(m, uint8_t *);
303 pcap_pkthdr.len = m->pkt_len;
304 pcap_pkthdr.caplen = m->data_len;
305 gettimeofday(&pcap_pkthdr.ts, NULL);
307 pcap_dump((uint8_t *)p->f_dump, &pcap_pkthdr, m_data);
308 pcap_dump_flush(p->f_dump);
316 sink_stats_read(void *port, struct rte_swx_port_out_stats *stats)
318 struct sink *p = port;
323 memcpy(stats, &p->stats, sizeof(p->stats));
327 * Summary of port operations
329 struct rte_swx_port_out_ops rte_swx_port_sink_ops = {
330 .create = sink_create,
332 .pkt_tx = sink_pkt_tx,
334 .stats_read = sink_stats_read,