这个sample是基于basicfw的。basicfw就是一个网口收到的包立即从另一个网口转发出去,非常简洁明了的程序,可以通过basicfw学习基础的DPDK发包API。RX / TX Callbacks 演示在接收和传输的数据包上使用用户定义的回调函数。

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2015 Intel Corporation
*/ #include <stdint.h>
#include <inttypes.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_cycles.h>
#include <rte_lcore.h>
#include <rte_mbuf.h> #define RX_RING_SIZE 1024
#define TX_RING_SIZE 1024 #define NUM_MBUFS 8191
#define MBUF_CACHE_SIZE 250
#define BURST_SIZE 32 static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
.ignore_offload_bitfield = 1,
},
}; static struct {
uint64_t total_cycles;
uint64_t total_pkts;
} latency_numbers; /* 回调函数的函数指针的格式设定:
一、rx
typedef uint16_t(* rte_rx_callback_fn)(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], uint16_t nb_pkts, uint16_t max_pkts, void *user_param)
参数:
1. port id
2. queue index
3. 接收的 burst pkt 所存放的 rte_mbuf 的数组
4. burst 中数据包的数量
5. 可以存储在pkts数组中的最大数据包数。
6. 最初配置回调时应用程序传入的任意用户参数 二、tx
typedef uint16_t(* rte_tx_callback_fn)(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], uint16_t nb_pkts, void *user_param)
参数:
1. port id
2. queue index
3. rte_mbuf的数组,里面的pkt即将被发送
4. burst 中数据包的数量
5. 最初配置回调时应用程序传入的任意用户参数
*/ // rx 队列的回调函数,添加接收时刻的时间戳
static uint16_t
add_timestamps(uint16_t port __rte_unused, uint16_t qidx __rte_unused,
struct rte_mbuf **pkts, uint16_t nb_pkts,
uint16_t max_pkts __rte_unused, void *_ __rte_unused)
{
unsigned i;
uint64_t now = rte_rdtsc(); // 用来获取时间戳计数器。 for (i = 0; i < nb_pkts; i++)
pkts[i]->udata64 = now; // 8字节用户数据
return nb_pkts;
} // tx 队列的回调函数,发送时计算时延
static uint16_t
calc_latency(uint16_t port __rte_unused, uint16_t qidx __rte_unused,
struct rte_mbuf **pkts, uint16_t nb_pkts, void *_ __rte_unused)
{
uint64_t cycles = 0;
uint64_t now = rte_rdtsc();
unsigned i; for (i = 0; i < nb_pkts; i++)
cycles += now - pkts[i]->udata64; // 在main.c中的全局struct中记录收到的包数量和总时延
latency_numbers.total_cycles += cycles;
latency_numbers.total_pkts += nb_pkts; if (latency_numbers.total_pkts > (100 * 1000 * 1000ULL)) { // 每十亿个包计算平均时延
printf("Latency = %"PRIu64" cycles\n",
latency_numbers.total_cycles / latency_numbers.total_pkts);
latency_numbers.total_cycles = latency_numbers.total_pkts = 0;
}
return nb_pkts;
} /*
* Initialises a given port using global settings and with the rx buffers
* coming from the mbuf_pool passed as parameter
*/
static inline int
port_init(uint16_t port, struct rte_mempool *mbuf_pool)
{
/*......*/
/*上面的部分和basicfw是一摸一样的*/ /* rte_eth_add_rx_callback() 这个API设定一个回调函数,特定 port id 和 rx queue index上每个收到的pkt(burst)都会进行突发调用。 参数四个:
1. port id
2. queue index
3. 回调函数的函数指针
4. 传递给回调函数的参数指针 返回值是一个指针,可以用于删除回调的API rte_eth_add_tx_callback()就是为 tx queue 上的发包配置回调函数。
*/ // 回调函数指针有统一的 typedef rte_eth_add_rx_callback(port, 0, add_timestamps, NULL);
rte_eth_add_tx_callback(port, 0, calc_latency, NULL); return 0;
} /*
* Main thread that does the work, reading from INPUT_PORT
* and writing to OUTPUT_PORT
*/ // lcore_main 与 basicfw 完全一样。
static __attribute__((noreturn)) void
lcore_main(void)
{
/*......*/
} /* Main function, does initialisation and calls the per-lcore functions */ // main 函数也与 basicfw 一样。
int
main(int argc, char *argv[])
{
/*......*/
}

执行情况

开了之后运行了一会,得到了输出。应该开一个外部的发包器比较好。

root@ubuntu:/home/chang/dpdk/examples/rxtx_callbacks/build# ./rxtx_callbacks -l 1 -n 4
EAL: Detected 8 lcore(s)
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Multi-process socket /var/run/.rte_unix
EAL: Probing VFIO support...
EAL: PCI device 0000:02:01.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:02.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:03.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:04.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
Port 0 MAC: 00 0c 29 f7 4d 25
Port 1 MAC: 00 0c 29 f7 4d 2f Core 1 forwarding packets. [Ctrl+C to quit]
Latency = 629 cycles
Latency = 787 cycles
^C

参考

sample guide:https://doc.dpdk.org/guides/sample_app_ug/rxtx_callbacks.html

API:ethdev, mbuf

最新文章

  1. android 生成.keystore文件
  2. iOS后台挂起程序 当程序到后台后,继续完成Long-Running Task 任务
  3. linux 学习8 权限管理
  4. linux编译curl库的动态库so(转)
  5. Cocos2d-X3.0 刨根问底(六)----- 调度器Scheduler类源码分析
  6. SPOJ 3273 - Order statistic set , Treap
  7. iOS: TableView如何刷新指定的cell 或section
  8. Linux试题及答案
  9. pymysql实现MySQL与Python交互
  10. myhaits if test判断字符串
  11. c语言结构体定义的几种形式
  12. Cs231n课堂内容记录-Lecture2-Part1 图像分类
  13. IdentityServer4【QuickStart】之使用ResourceOwnerPassword流程来保护API
  14. 【原创】运维基础之OpenResty
  15. PTA 堆栈操作合法性(20 分)
  16. [leetcode 12] Inter to Roman
  17. Bean Validation技术实现对Javabean的校验
  18. 学习Ruby你需要了解的相关知识(rvm, gem, bundle, rake, rails等)
  19. Code Signal_练习题_arrayChange
  20. 今天在Qt子界面中的Button,转到槽转不过去,报错Qt The class containing &#39;Ui::MainWindow&#39; could not be found in...

热门文章

  1. MAC mojave版本系统 破解软件
  2. 关于:url、视图函数、模板3者之间参数传递的理解
  3. (数据科学学习手札26)随机森林分类器原理详解&amp;Python与R实现
  4. springboot-web进阶(四)——单元测试
  5. 日志工具——log4j
  6. UWP 播放直播流 3MU8
  7. Centos 6.4 安装mysql-5.6.14-linux-glibc2.5-i686.tar.gz
  8. 2015306 白皎 《网络攻防》Exp4 恶意代码分析
  9. Maven Java项目添加Scala语言支持
  10. pythonDjango开发-创建django程序