Программа C для отправки пакетов из порта DPDK в порт ядраLinux

Ответить Пред. темаСлед. тема
Anonymous
 Программа C для отправки пакетов из порта DPDK в порт ядра

Сообщение Anonymous »

У меня есть две сетевые карты на одном сервере, соединенные друг с другом кабелем обратной связи QSFP. Каждая сетевая карта разделена на 8 портов, теперь я хочу передавать пакеты с помощью программы C DPDK на один из портов и получать входящие пакеты. на другой сетевой карте с использованием tcpdump (предпочтительнее в первую очередь).
Я привязал 0f:00.03 к порту dpdk и
Я попробовал описанный выше сценарий в dpdk-testpmd, и он работает хорошо,
При реализации программы на C я столкнулся с двумя проблемами:
  • цикл программы на C получает ошибку сегментации после отправки 32 пакетов
  • первые 32 отправленных пакета не перехватываются в tcpdump на другом порту сетевой карты, вместо этого я получаю одно сообщение отчета прослушивателя многоадресной рассылки v2 пакет каждый раз.
MakeFile:

Код: Выделить всё

# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation

# binary name
APP = dpdk_pcap_player

# all source are stored in SRCS-y
SRCS-y := dpdk_pcap_player.c

PKGCONF ?= pkg-config

# Build using pkg-config variables if possible
ifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0)
$(error "no installation of DPDK found")
endif

all: shared
.PHONY: shared static
shared: 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-config
ifeq ($(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")
endif
endif

CFLAGS += -DALLOW_EXPERIMENTAL_API

build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -lpcap

build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) -lpcap

build:
@mkdir -p $@

.PHONY: clean
clean:
rm -rf build/$(APP) build/$(APP)-static build/$(APP)-shared
test -d build && rmdir -p build || true

C-Программа:

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

#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 environment

struct 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;
}

Вывод на терминал:
Изображение
< /п>

Подробнее здесь: https://stackoverflow.com/questions/782 ... ernel-port
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»