之前写过一篇使用DPDK解析自定义数据包头部的文章。这篇文章将介绍如何使用DPDK来发送带有自定义头部的数据包!
实现思路
- 使用rte_pktmbuf_alloc在memory_pool中为数据包申请空间。
- 使用rte_pktmbuf_append往申请的空间中添加自定义头部。
- 往自定义头部中填入具体的内容。
核心代码
struct my_header {
uint16_t id;
uint16_t flag;
}
static struct rte_mbuf * generate_pkt(void) {
struct rte_mbuf *m;
struct my_header *my_hdr;
struct rte_ether_hdr *eth_hdr;
m = rte_pktmbuf_alloc(pktmbuf_pool); //先申请空间
my_hdr = (struct my_header *) rte_pktmbuf_append(m, sizeof(struct my_header)); //再加入自定义头部
my_hdr->id = rte_cpu_to_be_16(1); //填充实际内容,使用rte_cpu_to_be_16转成网络序
my_hdr->flag = rte_cpu_to_be_16(1234);
eth_hdr = (struct rte_ether_hdr *) rte_pktmbuf_append(m, sizeof(struct rte_ether_hdr)); //再加入以太网头部
// 省略填充以太网头部及加入IP,TCP头部的代码
// 调用rte_pktmbuf_append的顺序与你希望的头部顺序一致
// 本例子将自定义头部加在最外层
}
完整代码
我修改了$RTE_SDK/examples/l2fwd/main.c的代码,使其可以发送自定义头部的数据包。将以下代码全部复制到main.c中并make后即可使用。
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2016 Intel Corporation
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <sys/time.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_ip.h>
#include <rte_tcp.h>
static volatile bool force_quit;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
#define MEMPOOL_CACHE_SIZE 256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
/* ethernet addresses of ports */
static struct rte_ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS];
/* mask of enabled ports */
static uint32_t l2fwd_enabled_port_mask = 0;
static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
static struct rte_eth