Windows DPDK L2fwd-接收乱序数据包

发布于 2025-01-10 20:40:30 字数 3513 浏览 0 评论 0原文

我正在验证 DPDK 接收功能&为此,我在外部拍摄 PCAP 在 l2fwd 中添加代码以将收到的数据包转储到 pcap,l2fwd 转储的 pcap 具有来自射手的所有数据包,但其中一些数据包不按顺序排列。 射手已经过验证。

使用的 DPDK 版本-21.11

使用的 pcap 链接: https://wiki.wireshark.org/uploads/__moin_import__/attachments/SampleCaptures/tcp-ecn-sample.pcap 无序数据包是随机的。对于第一次运行,我没有看到混乱的数据包,但能够在第二次运行时复制该问题,第二、第三、第四个数据包混乱,顺序为 3、4、2。

下面是从 l2fwd 示例中截取的内容我们的修改为 //TESTCODE..

/* Read packet from RX queues. 8< */
for (i = 0; i < qconf->n_rx_port; i++) { 
            portid = qconf->rx_port_list[i];
            nb_rx = rte_eth_rx_burst(portid, 0,
                                            pkts_burst, MAX_PKT_BURST); 
            port_statistics[portid].rx += nb_rx; 
            for (j = 0; j < nb_rx; j++) {
                            m = pkts_burst[j];
                            // TESTCODE_STARTS
                            uint8_t* pkt = rte_pktmbuf_mtod(m, uint8_t*);
                            dump_to_pcap(pkt, rte_pktmbuf_pkt_len(m));
                            // TESTCODE_ENDS
                            rte_prefetch0(rte_pktmbuf_mtod(m, void *));
                            l2fwd_simple_forward(m, portid);
                          } 
}
/* >8 End of read packet from RX queues. */

以下是 dump_to_pcap 的代码

static int
dump_to_pcap(uint8_t* pkt, int pkt_len)
{

static FILE* fp = NULL;
static int init_file = 0;
if (0 == init_file) {

printf("Creating pcap\n");
char pcap_filename[256] = { 0 };
char Two_pcap_filename[256] = { 0 };
currentDateTime(pcap_filename);

sprintf(Two_pcap_filename,".\\Rx_%d_%s.pcap", 0, pcap_filename);
printf("FileSName to Create: %s\n", Two_pcap_filename);

fp = fopen(Two_pcap_filename, "wb");
if (NULL == fp) {
    printf("Unable to open file\n");
    fp = NULL;
}
else {
    printf("File create success..\n");
    init_file = 1;

    typedef struct pcap_file_header1 {
    unsigned int  magic; // a 32-bit "magic number"
    unsigned short version_major; //a 16-bit major version number
    unsigned short version_minor; //a 16-bit minor version number
    unsigned int thiszone; //a 32-bit "time zone offset" field that's actually not used, so ou can (and probably should) just make it 0
    unsigned int sigfigs;  //a 32-bit "time stamp accuracy" field that's not actually used,so you can (and probably should) just make it 0;
    unsigned int snaplen;  //a 32-bit "snapshot length" field
    unsigned int linktype; //a 32-bit "link layer type" field
    }dumpFileHdr;

    dumpFileHdr file_hdr;
    file_hdr.magic = 2712847316; //0xa1b2c3d4;
    file_hdr.version_major = 2; 
    file_hdr.version_minor = 4; 
    file_hdr.thiszone = 0;
    file_hdr.sigfigs = 0;
    file_hdr.snaplen = 65535;
    file_hdr.linktype = 1;
    fwrite((void*)(&file_hdr), sizeof(dumpFileHdr), 1, fp);
    //printf("Pcap Header written\n");
}
}

typedef struct pcap_pkthdr1 {
unsigned int ts_sec;      /* time stamp */
unsigned int ts_usec;
unsigned int caplen;     /* length of portion present */
unsigned int len;        /* length this packet (off wire) */
}dumpPktHdr;

dumpPktHdr pkt_hdr;
static int ts_sec = 1;
pkt_hdr.ts_sec = ts_sec++;
pkt_hdr.ts_usec = 0;
pkt_hdr.caplen = pkt_hdr.len = pkt_len;

if (NULL != fp) {
fwrite((void*)(&pkt_hdr), sizeof(dumpPktHdr), 1, fp);
fwrite((void*)(pkt), pkt_len, 1, fp);
fflush(fp);
}
return 0;
}

I am validating DPDK receive functionality & for this I'm shooting a pcap externally &
added code in l2fwd to dump received packets to pcap, the l2fwd dumped pcap have all the packets from shooter but some of them are not in sequence.
Shooter is already validated.

DPDK version in use-21.11

link of the pcap used : https://wiki.wireshark.org/uploads/__moin_import__/attachments/SampleCaptures/tcp-ecn-sample.pcap
Out of order packets are random. For the first run I saw no jumbled packets but was able to replicate the issue on second run with the 2nd,3rd,4th packets jumbled having order 3,4,2.

Below is snipped from l2fwd example & our modifications as //TESTCODE..

/* Read packet from RX queues. 8< */
for (i = 0; i < qconf->n_rx_port; i++) { 
            portid = qconf->rx_port_list[i];
            nb_rx = rte_eth_rx_burst(portid, 0,
                                            pkts_burst, MAX_PKT_BURST); 
            port_statistics[portid].rx += nb_rx; 
            for (j = 0; j < nb_rx; j++) {
                            m = pkts_burst[j];
                            // TESTCODE_STARTS
                            uint8_t* pkt = rte_pktmbuf_mtod(m, uint8_t*);
                            dump_to_pcap(pkt, rte_pktmbuf_pkt_len(m));
                            // TESTCODE_ENDS
                            rte_prefetch0(rte_pktmbuf_mtod(m, void *));
                            l2fwd_simple_forward(m, portid);
                          } 
}
/* >8 End of read packet from RX queues. */

Below is code for dump_to_pcap

static int
dump_to_pcap(uint8_t* pkt, int pkt_len)
{

static FILE* fp = NULL;
static int init_file = 0;
if (0 == init_file) {

printf("Creating pcap\n");
char pcap_filename[256] = { 0 };
char Two_pcap_filename[256] = { 0 };
currentDateTime(pcap_filename);

sprintf(Two_pcap_filename,".\\Rx_%d_%s.pcap", 0, pcap_filename);
printf("FileSName to Create: %s\n", Two_pcap_filename);

fp = fopen(Two_pcap_filename, "wb");
if (NULL == fp) {
    printf("Unable to open file\n");
    fp = NULL;
}
else {
    printf("File create success..\n");
    init_file = 1;

    typedef struct pcap_file_header1 {
    unsigned int  magic; // a 32-bit "magic number"
    unsigned short version_major; //a 16-bit major version number
    unsigned short version_minor; //a 16-bit minor version number
    unsigned int thiszone; //a 32-bit "time zone offset" field that's actually not used, so ou can (and probably should) just make it 0
    unsigned int sigfigs;  //a 32-bit "time stamp accuracy" field that's not actually used,so you can (and probably should) just make it 0;
    unsigned int snaplen;  //a 32-bit "snapshot length" field
    unsigned int linktype; //a 32-bit "link layer type" field
    }dumpFileHdr;

    dumpFileHdr file_hdr;
    file_hdr.magic = 2712847316; //0xa1b2c3d4;
    file_hdr.version_major = 2; 
    file_hdr.version_minor = 4; 
    file_hdr.thiszone = 0;
    file_hdr.sigfigs = 0;
    file_hdr.snaplen = 65535;
    file_hdr.linktype = 1;
    fwrite((void*)(&file_hdr), sizeof(dumpFileHdr), 1, fp);
    //printf("Pcap Header written\n");
}
}

typedef struct pcap_pkthdr1 {
unsigned int ts_sec;      /* time stamp */
unsigned int ts_usec;
unsigned int caplen;     /* length of portion present */
unsigned int len;        /* length this packet (off wire) */
}dumpPktHdr;

dumpPktHdr pkt_hdr;
static int ts_sec = 1;
pkt_hdr.ts_sec = ts_sec++;
pkt_hdr.ts_usec = 0;
pkt_hdr.caplen = pkt_hdr.len = pkt_len;

if (NULL != fp) {
fwrite((void*)(&pkt_hdr), sizeof(dumpPktHdr), 1, fp);
fwrite((void*)(pkt), pkt_len, 1, fp);
fflush(fp);
}
return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文