I have Two NIC cards in same server, connected to each other by QSFP Loopback Cable, Each NIC Card is divided into 8 ports, now i want to transmit packets using C program DPDK to one of the port and receive the incoming packets on another NIC card using tcpdump(preferred first).
I have binded 0f:00.03 to dpdk port andI have tried the above scenario in dpdk-testpmd and it is working fine,
For the C - program implementation i am facing two issues:
- the C program loop gets segmentation fault after sending 32 packets
- the first 32 sent packets are not getting captured in tcpdump on the other NIC port, instead i am getting a single Multicast Listener Report Message v2 packet every time.
MakeFile:
# SPDX-License-Identifier: BSD-3-Clause# Copyright(c) 2010-2014 Intel Corporation# binary nameAPP = dpdk_pcap_player# all source are stored in SRCS-ySRCS-y := dpdk_pcap_player.cPKGCONF ?= pkg-config# Build using pkg-config variables if possibleifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0)$(error "no installation of DPDK found")endifall: shared.PHONY: shared staticshared: build/$(APP)-shared ln -sf $(APP)-shared build/$(APP)static: build/$(APP)-static ln -sf $(APP)-static build/$(APP)PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)ifeq ($(MAKECMDGOALS),static)# check for broken pkg-configifeq ($(shell echo $(LDFLAGS_STATIC) | grep 'whole-archive.*l:lib.*no-whole-archive'),)$(warning "pkg-config output list does not contain drivers between 'whole-archive'/'no-whole-archive' flags.")$(error "Cannot generate statically-linked binaries with this version of pkg-config")endifendifCFLAGS += -DALLOW_EXPERIMENTAL_APIbuild/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -lpcapbuild/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) -lpcapbuild: @mkdir -p $@.PHONY: cleanclean: rm -rf build/$(APP) build/$(APP)-static build/$(APP)-shared test -d build && rmdir -p build || true
C -Program:
#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#include <netinet/in.h>#include <pcap.h>#include <rte_eal.h>#include <rte_ethdev.h>#define RX_RING_SIZE 1024#define TX_RING_SIZE 1024#define NUM_MBUFS 8191#define MBUF_CACHE_SIZE 250#define BURST_SIZE 32#define NB_MBUF (1024*8)#define ETH_PORT_ID 0 // Modify this according to your environmentstruct rte_eth_conf port_conf = { .rxmode = { .mq_mode = ETH_MQ_RX_NONE, }, .txmode = { .mq_mode = ETH_MQ_TX_NONE, },};static struct rte_mempool *mbuf_pool;int main(int argc, char *argv[]) { // Initialize DPDK int ret = rte_eal_init(argc, argv); if (ret < 0) { rte_exit(EXIT_FAILURE, "Error initializing DPDK\n"); } // Open Ethernet device if (rte_eth_dev_count_avail() == 0) { rte_exit(EXIT_FAILURE, "No Ethernet ports found\n"); } // Assuming only one port is available uint16_t port_id = ETH_PORT_ID; ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); if (ret != 0) { rte_exit(EXIT_FAILURE, "Failed to configure Ethernet port\n"); } // Initialize pcap pcap_t *pcap; char errbuf[PCAP_ERRBUF_SIZE]; // Open pcap file pcap = pcap_open_offline("c2_15scs_4_ant_256_frame_128.pcap", errbuf); if (pcap == NULL) { rte_exit(EXIT_FAILURE, "Error opening pcap file: %s\n", errbuf); } // Main loop for reading packets and sending them struct pcap_pkthdr *header; const u_char *packet_data; uint8_t tx_port = port_id; struct rte_mbuf *mbufs[BURST_SIZE]; mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NB_MBUF, 32, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_eth_dev_socket_id(port_id)); while (1) { int pkt_count = 0; // Read packets from pcap while (pkt_count < BURST_SIZE && pcap_next_ex(pcap, &header, &packet_data) == 1) { // Allocate mbuf mbufs[pkt_count] = rte_pktmbuf_alloc(mbuf_pool); if (mbufs[pkt_count] == NULL) { rte_exit(EXIT_FAILURE, "Failed to allocate mbuf\n"); } // Copy packet data to mbuf rte_memcpy(rte_pktmbuf_mtod(mbufs[pkt_count], void *), packet_data, header->caplen); printf("\npacket_data: %p\n", (char *)packet_data); mbufs[pkt_count]->data_len = header->caplen; mbufs[pkt_count]->pkt_len = header->len; pkt_count++; printf("\npkt_count: %d\n", pkt_count); } // Send packets if (pkt_count > 0) { printf("\nmbuf: %p\n", (void *)mbufs[0]); int sent = rte_eth_tx_burst(tx_port, 0, mbufs, pkt_count); printf("Packet Sent Status: %d", sent); if (sent < pkt_count) { // Handle error } } // Break if no more packets if (pkt_count < BURST_SIZE) break; } // Cleanup pcap_close(pcap); rte_eth_dev_stop(port_id); rte_eth_dev_close(port_id); rte_eal_cleanup(); return 0;}