xref: /dpdk/lib/port/rte_swx_port_source_sink.c (revision 7c10ca26f0cc7afbdfb91d2570fc242fa01fb0b2)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2020 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson #include <stdint.h>
599a2dd95SBruce Richardson #include <stdlib.h>
699a2dd95SBruce Richardson #include <string.h>
799a2dd95SBruce Richardson #ifdef RTE_PORT_PCAP
899a2dd95SBruce Richardson #include <pcap.h>
999a2dd95SBruce Richardson #endif
1099a2dd95SBruce Richardson #include <sys/time.h>
1199a2dd95SBruce Richardson 
1299a2dd95SBruce Richardson #include <rte_common.h>
1399a2dd95SBruce Richardson #include <rte_mbuf.h>
1499a2dd95SBruce Richardson #include <rte_hexdump.h>
1599a2dd95SBruce Richardson 
1699a2dd95SBruce Richardson #include "rte_swx_port_source_sink.h"
1799a2dd95SBruce Richardson 
1899a2dd95SBruce Richardson #define CHECK(condition)                                                       \
1999a2dd95SBruce Richardson do {                                                                           \
2099a2dd95SBruce Richardson 	if (!(condition))                                                      \
2199a2dd95SBruce Richardson 		return NULL;                                                   \
2299a2dd95SBruce Richardson } while (0)
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson #ifndef TRACE_LEVEL
2599a2dd95SBruce Richardson #define TRACE_LEVEL 0
2699a2dd95SBruce Richardson #endif
2799a2dd95SBruce Richardson 
2899a2dd95SBruce Richardson #if TRACE_LEVEL
2999a2dd95SBruce Richardson #define TRACE(...) printf(__VA_ARGS__)
3099a2dd95SBruce Richardson #else
3199a2dd95SBruce Richardson #define TRACE(...)
3299a2dd95SBruce Richardson #endif
3399a2dd95SBruce Richardson 
3499a2dd95SBruce Richardson /*
3599a2dd95SBruce Richardson  * Port SOURCE
3699a2dd95SBruce Richardson  */
3799a2dd95SBruce Richardson #ifdef RTE_PORT_PCAP
3899a2dd95SBruce Richardson 
3999a2dd95SBruce Richardson struct source {
4099a2dd95SBruce Richardson 	struct {
4199a2dd95SBruce Richardson 		struct rte_mempool *pool;
420317c452SYogesh Jangra 		uint64_t n_loops;
4399a2dd95SBruce Richardson 	} params;
4499a2dd95SBruce Richardson 	struct rte_swx_port_in_stats stats;
4599a2dd95SBruce Richardson 	struct rte_mbuf **pkts;
4699a2dd95SBruce Richardson 	uint32_t n_pkts;
4799a2dd95SBruce Richardson 	uint32_t pos;
4899a2dd95SBruce Richardson };
4999a2dd95SBruce Richardson 
5099a2dd95SBruce Richardson static void
source_free(void * port)5199a2dd95SBruce Richardson source_free(void *port)
5299a2dd95SBruce Richardson {
5399a2dd95SBruce Richardson 	struct source *p = port;
5499a2dd95SBruce Richardson 	uint32_t i;
5599a2dd95SBruce Richardson 
5699a2dd95SBruce Richardson 	if (!p)
5799a2dd95SBruce Richardson 		return;
5899a2dd95SBruce Richardson 
5999a2dd95SBruce Richardson 	for (i = 0; i < p->n_pkts; i++)
6099a2dd95SBruce Richardson 		rte_pktmbuf_free(p->pkts[i]);
6199a2dd95SBruce Richardson 
6299a2dd95SBruce Richardson 	free(p->pkts);
6399a2dd95SBruce Richardson 
6499a2dd95SBruce Richardson 	free(p);
6599a2dd95SBruce Richardson }
6699a2dd95SBruce Richardson 
6799a2dd95SBruce Richardson static void *
source_create(void * args)6899a2dd95SBruce Richardson source_create(void *args)
6999a2dd95SBruce Richardson {
7099a2dd95SBruce Richardson 	char pcap_errbuf[PCAP_ERRBUF_SIZE];
7199a2dd95SBruce Richardson 	struct rte_swx_port_source_params *params = args;
7299a2dd95SBruce Richardson 	struct source *p = NULL;
7399a2dd95SBruce Richardson 	pcap_t *f = NULL;
7499a2dd95SBruce Richardson 	uint32_t n_pkts_max, i;
7599a2dd95SBruce Richardson 
7699a2dd95SBruce Richardson 	/* Check input arguments. */
7799a2dd95SBruce Richardson 	CHECK(params);
7899a2dd95SBruce Richardson 	CHECK(params->pool);
7999a2dd95SBruce Richardson 	CHECK(params->file_name && params->file_name[0]);
8099a2dd95SBruce Richardson 	n_pkts_max = params->n_pkts_max ?
8199a2dd95SBruce Richardson 		params->n_pkts_max :
8299a2dd95SBruce Richardson 		RTE_SWX_PORT_SOURCE_PKTS_MAX;
8399a2dd95SBruce Richardson 
8499a2dd95SBruce Richardson 	/* Resource allocation. */
8599a2dd95SBruce Richardson 	f = pcap_open_offline(params->file_name, pcap_errbuf);
8699a2dd95SBruce Richardson 	if (!f)
8799a2dd95SBruce Richardson 		goto error;
8899a2dd95SBruce Richardson 
8999a2dd95SBruce Richardson 	p = calloc(1, sizeof(struct source));
9099a2dd95SBruce Richardson 	if (!p)
9199a2dd95SBruce Richardson 		goto error;
9299a2dd95SBruce Richardson 
9399a2dd95SBruce Richardson 	p->pkts = calloc(n_pkts_max, sizeof(struct rte_mbuf *));
9499a2dd95SBruce Richardson 	if (!p->pkts)
9599a2dd95SBruce Richardson 		goto error;
9699a2dd95SBruce Richardson 
9799a2dd95SBruce Richardson 	/* Initialization. */
9899a2dd95SBruce Richardson 	p->params.pool = params->pool;
9999a2dd95SBruce Richardson 
1000317c452SYogesh Jangra 	p->params.n_loops = params->n_loops ? params->n_loops : UINT64_MAX;
1010317c452SYogesh Jangra 
10299a2dd95SBruce Richardson 	/* PCAP file. */
10399a2dd95SBruce Richardson 	for (i = 0; i < n_pkts_max; i++) {
10499a2dd95SBruce Richardson 		struct pcap_pkthdr pcap_pkthdr;
10599a2dd95SBruce Richardson 		const uint8_t *pcap_pktdata;
10699a2dd95SBruce Richardson 		struct rte_mbuf *m;
10799a2dd95SBruce Richardson 		uint8_t *m_data;
10899a2dd95SBruce Richardson 
10999a2dd95SBruce Richardson 		/* Read new packet from PCAP file. */
11099a2dd95SBruce Richardson 		pcap_pktdata = pcap_next(f, &pcap_pkthdr);
11199a2dd95SBruce Richardson 		if (!pcap_pktdata)
11299a2dd95SBruce Richardson 			break;
11399a2dd95SBruce Richardson 
11499a2dd95SBruce Richardson 		/* Allocate new buffer from pool. */
11599a2dd95SBruce Richardson 		m = rte_pktmbuf_alloc(params->pool);
11699a2dd95SBruce Richardson 		if (!m)
11799a2dd95SBruce Richardson 			goto error;
11899a2dd95SBruce Richardson 		m_data = rte_pktmbuf_mtod(m, uint8_t *);
11999a2dd95SBruce Richardson 
12099a2dd95SBruce Richardson 		rte_memcpy(m_data, pcap_pktdata, pcap_pkthdr.caplen);
12199a2dd95SBruce Richardson 		m->data_len = pcap_pkthdr.caplen;
12299a2dd95SBruce Richardson 		m->pkt_len = pcap_pkthdr.caplen;
12399a2dd95SBruce Richardson 
12499a2dd95SBruce Richardson 		p->pkts[p->n_pkts] = m;
12599a2dd95SBruce Richardson 		p->n_pkts++;
12699a2dd95SBruce Richardson 	}
12799a2dd95SBruce Richardson 
12899a2dd95SBruce Richardson 	if (!p->n_pkts)
12999a2dd95SBruce Richardson 		goto error;
13099a2dd95SBruce Richardson 
13199a2dd95SBruce Richardson 	pcap_close(f);
13299a2dd95SBruce Richardson 	return p;
13399a2dd95SBruce Richardson 
13499a2dd95SBruce Richardson error:
13599a2dd95SBruce Richardson 	source_free(p);
13699a2dd95SBruce Richardson 	if (f)
13799a2dd95SBruce Richardson 		pcap_close(f);
13899a2dd95SBruce Richardson 	return NULL;
13999a2dd95SBruce Richardson }
14099a2dd95SBruce Richardson 
14199a2dd95SBruce Richardson static int
source_pkt_rx(void * port,struct rte_swx_pkt * pkt)14299a2dd95SBruce Richardson source_pkt_rx(void *port, struct rte_swx_pkt *pkt)
14399a2dd95SBruce Richardson {
14499a2dd95SBruce Richardson 	struct source *p = port;
14599a2dd95SBruce Richardson 	struct rte_mbuf *m_dst, *m_src;
14699a2dd95SBruce Richardson 	uint8_t *m_dst_data, *m_src_data;
14799a2dd95SBruce Richardson 
1480317c452SYogesh Jangra 	if (!p->params.n_loops)
1490317c452SYogesh Jangra 		return 0;
15099a2dd95SBruce Richardson 	/* m_src identification. */
15199a2dd95SBruce Richardson 	m_src = p->pkts[p->pos];
15299a2dd95SBruce Richardson 	m_src_data = rte_pktmbuf_mtod(m_src, uint8_t *);
15399a2dd95SBruce Richardson 
15499a2dd95SBruce Richardson 	/* m_dst allocation from pool. */
15599a2dd95SBruce Richardson 	m_dst = rte_pktmbuf_alloc(p->params.pool);
15699a2dd95SBruce Richardson 	if (!m_dst)
15799a2dd95SBruce Richardson 		return 0;
15899a2dd95SBruce Richardson 
15999a2dd95SBruce Richardson 	/* m_dst initialization. */
16099a2dd95SBruce Richardson 	m_dst->data_len = m_src->data_len;
16199a2dd95SBruce Richardson 	m_dst->pkt_len = m_src->pkt_len;
16299a2dd95SBruce Richardson 	m_dst->data_off = m_src->data_off;
16399a2dd95SBruce Richardson 
16499a2dd95SBruce Richardson 	m_dst_data = rte_pktmbuf_mtod(m_dst, uint8_t *);
16599a2dd95SBruce Richardson 	rte_memcpy(m_dst_data, m_src_data, m_src->data_len);
16699a2dd95SBruce Richardson 
16799a2dd95SBruce Richardson 	/* pkt initialization. */
16899a2dd95SBruce Richardson 	pkt->handle = m_dst;
16999a2dd95SBruce Richardson 	pkt->pkt = m_dst->buf_addr;
17099a2dd95SBruce Richardson 	pkt->offset = m_dst->data_off;
17199a2dd95SBruce Richardson 	pkt->length = m_dst->pkt_len;
17299a2dd95SBruce Richardson 
17399a2dd95SBruce Richardson 	TRACE("[Source port] Pkt RX (%u bytes at offset %u)\n",
17499a2dd95SBruce Richardson 	      pkt->length,
17599a2dd95SBruce Richardson 	      pkt->offset);
17699a2dd95SBruce Richardson 	if (TRACE_LEVEL)
17799a2dd95SBruce Richardson 		rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
17899a2dd95SBruce Richardson 
17999a2dd95SBruce Richardson 	/* port stats update. */
18099a2dd95SBruce Richardson 	p->stats.n_pkts++;
18199a2dd95SBruce Richardson 	p->stats.n_bytes += pkt->length;
18299a2dd95SBruce Richardson 
18399a2dd95SBruce Richardson 	/* m_src next. */
18499a2dd95SBruce Richardson 	p->pos++;
1850317c452SYogesh Jangra 	if (p->pos == p->n_pkts) {
18699a2dd95SBruce Richardson 		p->pos = 0;
1870317c452SYogesh Jangra 		p->params.n_loops--;
1880317c452SYogesh Jangra 	}
18999a2dd95SBruce Richardson 
19099a2dd95SBruce Richardson 	return 1;
19199a2dd95SBruce Richardson }
19299a2dd95SBruce Richardson 
19399a2dd95SBruce Richardson static void
source_stats_read(void * port,struct rte_swx_port_in_stats * stats)19499a2dd95SBruce Richardson source_stats_read(void *port, struct rte_swx_port_in_stats *stats)
19599a2dd95SBruce Richardson {
19699a2dd95SBruce Richardson 	struct source *p = port;
19799a2dd95SBruce Richardson 
19899a2dd95SBruce Richardson 	if (!p || !stats)
19999a2dd95SBruce Richardson 		return;
20099a2dd95SBruce Richardson 
20199a2dd95SBruce Richardson 	memcpy(stats, &p->stats, sizeof(p->stats));
20299a2dd95SBruce Richardson }
20399a2dd95SBruce Richardson 
20499a2dd95SBruce Richardson struct rte_swx_port_in_ops rte_swx_port_source_ops = {
20599a2dd95SBruce Richardson 	.create = source_create,
20699a2dd95SBruce Richardson 	.free = source_free,
20799a2dd95SBruce Richardson 	.pkt_rx = source_pkt_rx,
20899a2dd95SBruce Richardson 	.stats_read = source_stats_read,
20999a2dd95SBruce Richardson };
21099a2dd95SBruce Richardson 
21199a2dd95SBruce Richardson #else
21299a2dd95SBruce Richardson 
21399a2dd95SBruce Richardson struct rte_swx_port_in_ops rte_swx_port_source_ops = {
21499a2dd95SBruce Richardson 	.create = NULL,
21599a2dd95SBruce Richardson 	.free = NULL,
21699a2dd95SBruce Richardson 	.pkt_rx = NULL,
21799a2dd95SBruce Richardson 	.stats_read = NULL,
21899a2dd95SBruce Richardson };
21999a2dd95SBruce Richardson 
22099a2dd95SBruce Richardson #endif
22199a2dd95SBruce Richardson 
22299a2dd95SBruce Richardson /*
22399a2dd95SBruce Richardson  * Port SINK
22499a2dd95SBruce Richardson  */
22599a2dd95SBruce Richardson struct sink {
22699a2dd95SBruce Richardson 	struct rte_swx_port_out_stats stats;
22799a2dd95SBruce Richardson 
22899a2dd95SBruce Richardson #ifdef RTE_PORT_PCAP
22999a2dd95SBruce Richardson 	pcap_t *f_pcap;
23099a2dd95SBruce Richardson 	pcap_dumper_t *f_dump;
23199a2dd95SBruce Richardson #endif
23299a2dd95SBruce Richardson };
23399a2dd95SBruce Richardson 
23499a2dd95SBruce Richardson static void
sink_free(void * port)23599a2dd95SBruce Richardson sink_free(void *port)
23699a2dd95SBruce Richardson {
23799a2dd95SBruce Richardson 	struct sink *p = port;
23899a2dd95SBruce Richardson 
23999a2dd95SBruce Richardson 	if (!p)
24099a2dd95SBruce Richardson 		return;
24199a2dd95SBruce Richardson 
24299a2dd95SBruce Richardson #ifdef RTE_PORT_PCAP
24399a2dd95SBruce Richardson 	if (p->f_dump)
24499a2dd95SBruce Richardson 		pcap_dump_close(p->f_dump);
24599a2dd95SBruce Richardson 	if (p->f_pcap)
24699a2dd95SBruce Richardson 		pcap_close(p->f_pcap);
24799a2dd95SBruce Richardson #endif
24899a2dd95SBruce Richardson 
24999a2dd95SBruce Richardson 	free(p);
25099a2dd95SBruce Richardson }
25199a2dd95SBruce Richardson 
25299a2dd95SBruce Richardson static void *
sink_create(void * args __rte_unused)25399a2dd95SBruce Richardson sink_create(void *args __rte_unused)
25499a2dd95SBruce Richardson {
25599a2dd95SBruce Richardson 	struct sink *p;
25699a2dd95SBruce Richardson 
25799a2dd95SBruce Richardson 	/* Memory allocation. */
25899a2dd95SBruce Richardson 	p = calloc(1, sizeof(struct sink));
25999a2dd95SBruce Richardson 	if (!p)
26099a2dd95SBruce Richardson 		goto error;
26199a2dd95SBruce Richardson 
26299a2dd95SBruce Richardson #ifdef RTE_PORT_PCAP
26399a2dd95SBruce Richardson 	if (args) {
26499a2dd95SBruce Richardson 		struct rte_swx_port_sink_params *params = args;
26599a2dd95SBruce Richardson 
26699a2dd95SBruce Richardson 		if (params->file_name && params->file_name[0]) {
26799a2dd95SBruce Richardson 			p->f_pcap = pcap_open_dead(DLT_EN10MB, 65535);
26899a2dd95SBruce Richardson 			if (!p->f_pcap)
26999a2dd95SBruce Richardson 				goto error;
27099a2dd95SBruce Richardson 
27199a2dd95SBruce Richardson 			p->f_dump = pcap_dump_open(p->f_pcap,
27299a2dd95SBruce Richardson 						   params->file_name);
27399a2dd95SBruce Richardson 			if (!p->f_dump)
27499a2dd95SBruce Richardson 				goto error;
27599a2dd95SBruce Richardson 		}
27699a2dd95SBruce Richardson 	}
27799a2dd95SBruce Richardson #endif
27899a2dd95SBruce Richardson 
27999a2dd95SBruce Richardson 	return p;
28099a2dd95SBruce Richardson 
28199a2dd95SBruce Richardson error:
28299a2dd95SBruce Richardson 	sink_free(p);
28399a2dd95SBruce Richardson 	return NULL;
28499a2dd95SBruce Richardson }
28599a2dd95SBruce Richardson 
28699a2dd95SBruce Richardson static void
sink_pkt_tx(void * port,struct rte_swx_pkt * pkt)28799a2dd95SBruce Richardson sink_pkt_tx(void *port, struct rte_swx_pkt *pkt)
28899a2dd95SBruce Richardson {
28999a2dd95SBruce Richardson 	struct sink *p = port;
29099a2dd95SBruce Richardson 	struct rte_mbuf *m = pkt->handle;
29199a2dd95SBruce Richardson 
29299a2dd95SBruce Richardson 	TRACE("[Sink port] Pkt TX (%u bytes at offset %u)\n",
29399a2dd95SBruce Richardson 	      pkt->length,
29499a2dd95SBruce Richardson 	      pkt->offset);
29599a2dd95SBruce Richardson 	if (TRACE_LEVEL)
29699a2dd95SBruce Richardson 		rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
29799a2dd95SBruce Richardson 
298b94eb6cdSCristian Dumitrescu 	m->data_len = (uint16_t)(pkt->length + m->data_len - m->pkt_len);
29999a2dd95SBruce Richardson 	m->pkt_len = pkt->length;
30099a2dd95SBruce Richardson 	m->data_off = (uint16_t)pkt->offset;
30199a2dd95SBruce Richardson 
302*7c10ca26SCristian Dumitrescu 	p->stats.n_pkts_drop++;
303*7c10ca26SCristian Dumitrescu 	p->stats.n_bytes_drop += pkt->length;
30499a2dd95SBruce Richardson 
30599a2dd95SBruce Richardson #ifdef RTE_PORT_PCAP
30699a2dd95SBruce Richardson 	if (p->f_dump) {
30799a2dd95SBruce Richardson 		struct pcap_pkthdr pcap_pkthdr;
30899a2dd95SBruce Richardson 		uint8_t *m_data = rte_pktmbuf_mtod(m, uint8_t *);
30999a2dd95SBruce Richardson 
31099a2dd95SBruce Richardson 		pcap_pkthdr.len = m->pkt_len;
31199a2dd95SBruce Richardson 		pcap_pkthdr.caplen = m->data_len;
31299a2dd95SBruce Richardson 		gettimeofday(&pcap_pkthdr.ts, NULL);
31399a2dd95SBruce Richardson 
31499a2dd95SBruce Richardson 		pcap_dump((uint8_t *)p->f_dump, &pcap_pkthdr, m_data);
31599a2dd95SBruce Richardson 		pcap_dump_flush(p->f_dump);
31699a2dd95SBruce Richardson 	}
31799a2dd95SBruce Richardson #endif
31899a2dd95SBruce Richardson 
31999a2dd95SBruce Richardson 	rte_pktmbuf_free(m);
32099a2dd95SBruce Richardson }
32199a2dd95SBruce Richardson 
32299a2dd95SBruce Richardson static void
__sink_pkt_clone_tx(void * port,struct rte_swx_pkt * pkt,uint32_t truncation_length __rte_unused)323b94eb6cdSCristian Dumitrescu __sink_pkt_clone_tx(void *port, struct rte_swx_pkt *pkt, uint32_t truncation_length __rte_unused)
324b94eb6cdSCristian Dumitrescu {
325b94eb6cdSCristian Dumitrescu 	struct sink *p = port;
326b94eb6cdSCristian Dumitrescu 	struct rte_mbuf *m = pkt->handle;
327b94eb6cdSCristian Dumitrescu 
328b94eb6cdSCristian Dumitrescu 	TRACE("[Sink port] Pkt TX (%u bytes at offset %u) (clone)\n",
329b94eb6cdSCristian Dumitrescu 	      pkt->length,
330b94eb6cdSCristian Dumitrescu 	      pkt->offset);
331b94eb6cdSCristian Dumitrescu 	if (TRACE_LEVEL)
332b94eb6cdSCristian Dumitrescu 		rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
333b94eb6cdSCristian Dumitrescu 
334b94eb6cdSCristian Dumitrescu 	m->data_len = (uint16_t)(pkt->length + m->data_len - m->pkt_len);
335b94eb6cdSCristian Dumitrescu 	m->pkt_len = pkt->length;
336b94eb6cdSCristian Dumitrescu 	m->data_off = (uint16_t)pkt->offset;
337b94eb6cdSCristian Dumitrescu 
338*7c10ca26SCristian Dumitrescu 	p->stats.n_pkts_drop++;
339*7c10ca26SCristian Dumitrescu 	p->stats.n_bytes_drop += pkt->length;
340b94eb6cdSCristian Dumitrescu 	p->stats.n_pkts_clone++;
341b94eb6cdSCristian Dumitrescu 
342b94eb6cdSCristian Dumitrescu #ifdef RTE_PORT_PCAP
343b94eb6cdSCristian Dumitrescu 	if (p->f_dump) {
344b94eb6cdSCristian Dumitrescu 		struct pcap_pkthdr pcap_pkthdr;
345b94eb6cdSCristian Dumitrescu 		uint8_t *m_data = rte_pktmbuf_mtod(m, uint8_t *);
346b94eb6cdSCristian Dumitrescu 
347b94eb6cdSCristian Dumitrescu 		pcap_pkthdr.len = m->pkt_len;
348b94eb6cdSCristian Dumitrescu 		pcap_pkthdr.caplen = RTE_MIN(m->data_len, truncation_length);
349b94eb6cdSCristian Dumitrescu 		gettimeofday(&pcap_pkthdr.ts, NULL);
350b94eb6cdSCristian Dumitrescu 
351b94eb6cdSCristian Dumitrescu 		pcap_dump((uint8_t *)p->f_dump, &pcap_pkthdr, m_data);
352b94eb6cdSCristian Dumitrescu 		pcap_dump_flush(p->f_dump);
353b94eb6cdSCristian Dumitrescu 	}
354b94eb6cdSCristian Dumitrescu #endif
355b94eb6cdSCristian Dumitrescu }
356b94eb6cdSCristian Dumitrescu 
357b94eb6cdSCristian Dumitrescu static void
sink_pkt_fast_clone_tx(void * port,struct rte_swx_pkt * pkt)358b94eb6cdSCristian Dumitrescu sink_pkt_fast_clone_tx(void *port, struct rte_swx_pkt *pkt)
359b94eb6cdSCristian Dumitrescu {
360b94eb6cdSCristian Dumitrescu 	__sink_pkt_clone_tx(port, pkt, UINT32_MAX);
361b94eb6cdSCristian Dumitrescu }
362b94eb6cdSCristian Dumitrescu 
363b94eb6cdSCristian Dumitrescu static void
sink_pkt_clone_tx(void * port,struct rte_swx_pkt * pkt,uint32_t truncation_length)364b94eb6cdSCristian Dumitrescu sink_pkt_clone_tx(void *port, struct rte_swx_pkt *pkt, uint32_t truncation_length)
365b94eb6cdSCristian Dumitrescu {
366b94eb6cdSCristian Dumitrescu 	__sink_pkt_clone_tx(port, pkt, truncation_length);
367b94eb6cdSCristian Dumitrescu }
368b94eb6cdSCristian Dumitrescu 
369b94eb6cdSCristian Dumitrescu static void
sink_stats_read(void * port,struct rte_swx_port_out_stats * stats)37099a2dd95SBruce Richardson sink_stats_read(void *port, struct rte_swx_port_out_stats *stats)
37199a2dd95SBruce Richardson {
37299a2dd95SBruce Richardson 	struct sink *p = port;
37399a2dd95SBruce Richardson 
37499a2dd95SBruce Richardson 	if (!p || !stats)
37599a2dd95SBruce Richardson 		return;
37699a2dd95SBruce Richardson 
37799a2dd95SBruce Richardson 	memcpy(stats, &p->stats, sizeof(p->stats));
37899a2dd95SBruce Richardson }
37999a2dd95SBruce Richardson 
38099a2dd95SBruce Richardson /*
38199a2dd95SBruce Richardson  * Summary of port operations
38299a2dd95SBruce Richardson  */
38399a2dd95SBruce Richardson struct rte_swx_port_out_ops rte_swx_port_sink_ops = {
38499a2dd95SBruce Richardson 	.create = sink_create,
38599a2dd95SBruce Richardson 	.free = sink_free,
38699a2dd95SBruce Richardson 	.pkt_tx = sink_pkt_tx,
387b94eb6cdSCristian Dumitrescu 	.pkt_fast_clone_tx = sink_pkt_fast_clone_tx,
388b94eb6cdSCristian Dumitrescu 	.pkt_clone_tx = sink_pkt_clone_tx,
38999a2dd95SBruce Richardson 	.flush = NULL,
39099a2dd95SBruce Richardson 	.stats_read = sink_stats_read,
39199a2dd95SBruce Richardson };
392