基于udp协议
系列文章目录
1.dpdk实现receive接收数据 2.dpdk实现send发送数据 3.dpdk实现arp
前言
dpdk基于udp协议实现receive接收数据
一、头文件
#include <stdio.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>
#include <stdio.h>
#include <arpa/inet.h>
二、定义几个常量
#define NUM_MBUFS (4096 - 1)
#define BURST_SIZE 32
int gDpdkPortId = 0;
三、设置端口默认信息
static const struct rte_eth_conf port_conf_default = {
.rxmode = {.max_rx_pkt_len = RTE_ETHER_MAX_LEN}};
static const 既是只读(const)的,又是只在当前模块中可见(static)的.rxmode 结构的指定初始化项目使用点运算符和成员名(而不是方括号和索引值)来标识具体的元素,跟数组类似
四、初始化出数据的网口
eth0网卡由dpdk接管,负责接收网络数据
static void ng_init_port(struct rte_mempool *mbuf_pool)
{
uint16_t nb_sys_ports = rte_eth_dev_count_avail();
if (nb_sys_ports == 0)
{
rte_exit(EXIT_FAILURE, "No Supported eth found\n");
}
struct rte_eth_dev_info dev_info;
rte_eth_dev_info_get(gDpdkPortId, &dev_info);
const int num_rx_queues = 1;
const int num_tx_queues = 0;
struct rte_eth_conf port_conf = port_conf_default;
rte_eth_dev_configure(gDpdkPortId, num_rx_queues, num_tx_queues, &port_conf);
if (rte_eth_rx_queue_setup(gDpdkPortId, 0, 128,
rte_eth_dev_socket_id(gDpdkPortId), NULL, mbuf_pool) < 0)
{
rte_exit(EXIT_FAILURE, "Could not setup RX queue\n");
}
if (rte_eth_dev_start(gDpdkPortId) < 0)
{
rte_exit(EXIT_FAILURE, "Could not start\n");
}
}
五、main函数
主要是对网络中的数据进行一层一层解包
int main(int argc, char *argv[])
{
if (rte_eal_init(argc, argv) < 0)
{
rte_exit(EXIT_FAILURE, "Error with EAL init\n");
}
struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create(
"mbuf pool", NUM_MBUFS, 0, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
if (NULL == mbuf_pool)
{
rte_exit(EXIT_FAILURE, "Could not create mbuf pool\n");
}
ng_init_port(mbuf_pool);
while (1)
{
struct rte_mbuf *mbufs[BURST_SIZE];
unsigned num_recvd = rte_eth_rx_burst(gDpdkPortId, 0, mbufs, BURST_SIZE);
if (num_recvd > BURST_SIZE)
{
rte_exit(EXIT_FAILURE, "Error receiving from eth\n");
}
unsigned i = 0;
for (i = 0; i < num_recvd; i++)
{
struct rte_ether_hdr *ehdr = rte_pktmbuf_mtod(mbufs[i], struct rte_ether_hdr *);
if (ehdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4))
{
continue;
}
struct rte_ipv4_hdr *iphdr =
rte_pktmbuf_mtod_offset(mbufs[i], struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));
if (iphdr->next_proto_id == IPPROTO_UDP)
{
struct rte_udp_hdr *udphdr = (struct rte_udp_hdr *)(iphdr + 1);
uint16_t length = ntohs(udphdr->dgram_len);
uint16_t udp_data_len = length - sizeof(struct rte_udp_hdr) + 1;
char buff[udp_data_len];
memset(buff, 0, udp_data_len);
--udp_data_len;
memcpy(buff, (udphdr + 1), udp_data_len);
struct in_addr addr;
addr.s_addr = iphdr->src_addr;
printf("src: %s:%d, ", inet_ntoa(addr), ntohs(udphdr->src_port));
addr.s_addr = iphdr->dst_addr;
printf("dst: %s:%d, %s\n",
inet_ntoa(addr), ntohs(udphdr->dst_port), buff);
rte_pktmbuf_free(mbufs[i]);
}
}
}
}
运行结果
运行可得到以下结果:
|