dpdk网络转发环境的搭建
文章目录
- 前言
- ip命令的使用
- 配置dpdk-basicfwd需要的网络结构
- 测试dpdk-basicfwd
- dpdk-basicfwd代码分析
- 附录
- basicfwd在tcp转发时的失败抓包信息
- DPDK的相关设置
前言
上手dpdk有两难。其一为环境搭建。被绑定之后的网卡没有IP,我如何给它发送数据呢?当然,可以通过网桥将一个正常的网卡和被绑定的网卡互相连接。但对于日常写demo实验中,这并不方便。本文尝试用vire-pair来避免使用硬件网桥,使用namespace来隔离网络。其二是,关于端口初始化。我没有搞清楚每个选项设置的必然原因,但是这里会列出端口初始化的基本流程。
最后验证,借助Basic Forwarding Sample Application — Data Plane Development Kit 23.11.0 documentation可以将网络上不相连接两个端口,可以互相ping通。但是在验证tcp转发的时候,抓包显示tcp checksum incorrect。相关报错循序见后文。此事必有蹊跷。
注:本文验证网络转发的代码来自dpdk/examples/skeleton at main · DPDK/dpdk。我将它移动到该仓库目录中。
ip命令的使用
在组建虚拟网络结构之前,我们需要先了解IP命令的使用。参考自:
- ip 命令 - Router Lab 实验文档
- ip(8) - Linux man page
ip命令的总体组成如下。
ip [ OPTIONS ] OBJECT { COMMAND | help }OBJECT := { link | addr | addrlabel | route | rule | neigh | tunnel | maddr | mroute | monitor }OPTIONS := { -V[ersion] | -s[tatistics] | -r[esolve] | -f[amily] { inet | inet6 | ipx | dnet | link } | -o[neline] }
ip address - protocol address management.
每个设备必须有一个IP地址,才能使用对应的协议(IPV4/IPV6)。可以通过ip address help
查看使用方法。
# 列出所有网口信息和地址信息
ip address show# 设置网络
ip addr add $addr/$prefix_len dev $interface
ip link - network device configuration。
使用ip link
来显示和修改网络设备的状态。具体使用方法,可以通过help查看。
# 查看设备状态
ip link show# 创建两个虚拟以太网设备,它们之间直接相连
## ref: https://man7.org/linux/man-pages/man4/veth.4.html
### 在一对设备中的一个设备上传输的数据包会立即在其他设备上收到。当任一设备出现故障时,该对的链路状态为关闭。
### 这两个veth可以处在不同的网络命名空间中
## 如果有天希望三个veth可以互通,这似乎有点麻烦,我还没搞明白:https://superuser.com/questions/764986/howto-setup-a-veth-virtual-network
## 这里还有篇veth-pair配置的不错的介绍:https://www.cnblogs.com/bakari/p/10613710.html
ip link add $name1 type veth peer name $name2
ip route - routing table management.
操纵路由表。
# 查看路由表
ip route show
配置dpdk-basicfwd需要的网络结构
了解了ip命令的基本使用后,我们来配置下dpdk-basicfwd所需的网络结构。网络中包含:两对veth-pair, 其中veth1和veth2互连,veth3和veth4互连; veth1在名为nsA的namespace中; veth4在名为nsB的namespace中; dpdk-basicfwd将veth2收到的流量转发到veth3,veth3收到的流量转发到veth2; 网络总体结构图如下所示:
下面我们按照上图所示,进行网络创建。
先设置一对虚拟以太网卡,并设置IP/mask。注意此时这两者无法互相ping通,但是可以通过lo口互通的,见: Linux 虚拟网络设备 veth-pair 详解,看这一篇就够了 - bakari - 博客园
ip link add veth1 type veth peer name veth2
ip link set veth1 up
ip link set veth2 up
ip address add 10.0.0.2/24 dev veth1
ip address add 10.0.0.3/24 dev veth2#测试下上面的配置是否可以联通。
## -l表示listen; -s表示veth2在80开启监听端口;
## -k表示处理完一个连接后继续监听新的连接,而不是退出
#nc -k -l -s 10.0.0.3 -p 80## 从10.0.0.2发出流量到10.0.0.3:80 端口
#echo "hello world" | nc -s 10.0.0.2 -w 1 10.0.0.3 80
接着,我们再设置另一对虚拟以太网。
ip link add veth3 type veth peer name veth4
ip link set veth3 up
ip link set veth4 up
ip address add 172.16.0.2/24 dev veth3
ip address add 172.16.0.3/24 dev veth4
为了避免veth1和veth4通过lo口进行通信。将veth1和veth4放在不同的namespace中。
# 添加两个命名空间
ip netns add nsA
ip netns add nsB# 将veth1加入命名空间nsA; 需要重写进行网卡信息的配置
## 此时veth1能ping通veth2了
ip link set veth1 netns nsA
ip netns exec nsA /bin/bash
ip link set veth1 up
ip address add 10.0.0.2/24 dev veth1
ping 10.0.0.3# 将veth4加入命名空间nsB; 然后进入命名空间,设置ip并启用
## 此时veth4能ping通veth3了
ip link set veth4 netns nsB
ip netns exec nsB /bin/bash
ip link set veth4 up
ip address add 172.16.0.3/24 dev veth4
ping 172.16.0.2
端口配置后,还需要设置下路由:在nsA中,让访问veth4的流量,从veth1端口走。在nsB中,让访问veth1的流量,从veth4端口走。
# nsB中
ip netns exec nsB /bin/bash
ip route add 10.0.0.2 dev veth4
# tcpdump -nn -vv -l -i veth4
# nc -k -l -s 172.16.0.3 -p 80# nsA中
ip netns exec nsA /bin/bash
ip route add 172.16.0.3 dev veth1
# ping 172.16.0.3
# echo "hello world" | nc -s 10.0.0.2 -w 5 172.16.0.3 80
最终的结果:
- veth1和veth2可以通过veth-pair跨namespcae通信。
- veth3和veth4可以通过veth-pair跨namespcae通信。
- 但是veth1和veth2由于不在同一个namespace,又没有veth-pair,所以相互之间无法通信。
测试dpdk-basicfwd
为什么--vdev
这个参数可以呢,它是什么原理?我也不知道,照葫芦画瓢参考自:odp-dpdk/platform/linux-dpdk/README at master · OpenDataPlane/odp-dpdk
./dpdk-skeleton -l 1 -n 4 --vdev "eth_pcap0,iface=veth2" --vdev "eth_pcap1,iface=veth3"
dpdk-basicfwd代码分析
200行的代码,很快就能看完一遍。具体的API使用见官方文档,这里简述下流程。
首先是内存池和cpu相关的初始化,这个和存储架构相关。大体知道知道这些含义即可:NUMA node > socket > core > logical processor。相关内容见:CPU 拓扑:从 SMP 谈到 NUMA (理论篇) | 猿大白
接着是端口相关的初始化,简单的基本流程是:查看当前端口的信息->对端口进行配置->设置总共的接收/发送描述符数->每个队列可以使用的接收/发送描述符数。这部分的结构可能是这样的。
然后就是转发。从一个端口接收到数据,然后让另一个端口发送这部分数据。
附录
basicfwd在tcp转发时的失败抓包信息
# nsB中启动监听
nc -l -s 172.16.0.3 -p 80# nsA中发起请求
echo "hello world" | nc -s 10.0.0.2 -w 5 172.16.0.3 80# nsB中抓包信息
## 可以看到 cksum 0xb643 (incorrect -> 0xfc92)
tcpdump -nn -vv -l -i veth4
tcpdump: listening on veth4, link-type EN10MB (Ethernet), capture size 262144 bytes
22:24:39.112851 IP (tos 0x0, ttl 64, id 21121, offset 0, flags [DF], proto TCP (6), length 60)10.0.0.2.38177 > 172.16.0.3.80: Flags [S], cksum 0xb643 (incorrect -> 0xfc92), seq 2659543870, win 64240, options [mss 1460,sackOK,TS val 3763804890 ecr 0,nop,wscale 7], length 0
22:24:40.136180 IP (tos 0x0, ttl 64, id 21122, offset 0, flags [DF], proto TCP (6), length 60)10.0.0.2.38177 > 172.16.0.3.80: Flags [S], cksum 0xb643 (incorrect -> 0xf893), seq 2659543870, win 64240, options [mss 1460,sackOK,TS val 3763805913 ecr 0,nop,wscale 7], length 0
22:24:42.232702 IP (tos 0x0, ttl 64, id 21123, offset 0, flags [DF], proto TCP (6), length 60)10.0.0.2.38177 > 172.16.0.3.80: Flags [S], cksum 0xb643 (incorrect -> 0xf05f), seq 2659543870, win 64240, options [mss 1460,sackOK,TS val 3763808013 ecr 0,nop,wscale 7], length 0
22:24:44.140469 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.16.0.3 tell 10.0.0.2, length 28
22:24:44.140480 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.16.0.3 is-at 8a:06:58:68:ec:d8, length 2
DPDK的相关设置
绑定网卡。
ip命令创建的虚拟以太网卡,dpdk-devbind.py
是无法绑定的。如果绑定真实的网卡,需要先有驱动,然后进行绑定。
# 包管理器方式下载驱动
## ubuntu
sudo apt install dpdk-igb-uio-dkms# 源码编译的方式生成驱动
# 编译igb_uio驱动; 在wsl中会编译失败,需要在linux环境中编译
git clone git://dpdk.org/dpdk-kmods
cd dpdk-kmods/linux
make# 绑定网卡
## 先停止网卡
ip link set enp0s3 down
## 然后安装驱动模块
modprobe igb_uio
## 然后绑定网卡
./dpdk-devbind.py --bind=igb_uio enp0s3
## 查看绑定后的信息
./dpdk-devbind.py --status
dpdk源码编译
关于编译参数,自行参考官方手册和源码。
git clone git@github.com:DPDK/dpdk.git# 初学还是不要直接用dev分支的代码比较好。
## 我踩了一个坑:ALLOW_EXPERIMENTAL_API这个宏,在dev中是默认开启的,但是在发布的tag中是关闭的
git checkout v23.11# cpu_instruction_set还是设置为corei7吧。
## 如果不设置这个选项,在dev分支中,debug版本调试的时候,会出现crash,提示指令相关的报错
meson setup -Dcpu_instruction_set=corei7 -Dbuildtype=debug -Dexamples=all -Dprefix=/home/dacao/work/3rdlib/dpdk build
cd build
ninja
ninja install
在cmake中链接dpdk库。
自行编写的dpdk程序链接dpdk库的时候,要加上--whole-archive
。否则不会将pmd相关的库不会打包到程序中。在CmakeLists中使用pkgconfig, 不会带上--whole-archive
这个参数。原因我不知道到。我还没有去查阅pkgconfig的文件格式和cmake对其的使用。可以使用下面的配置。
cmake_minimum_required(VERSION 3.11)project(dpdk-skeleton)# arch的参数和编译dpdk时的cpu_instruction_set参数保持一致
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=corei7")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=corei7")find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBDPDK REQUIRED libdpdk)
include_directories(${LIBDPDK_STATIC_INCLUDE_DIRS})
# link_directories(${LIBDPDK_STATIC_LIBRARY_DIRS})
# message(STATUS "LIBDPDK_STATIC_LIBRARIES: ${LIBDPDK_STATIC_LIBRARIES}")
# message(STATUS "LIBDPDK_STATIC_INCLUDE_DIRS: ${LIBDPDK_STATIC_INCLUDE_DIRS}")
message(STATUS "LIBDPDK_LIBDIR: ${LIBDPDK_LIBDIR}")add_custom_target(compress_dpdk_librariesCOMMAND rm -rf libdpdks.aCOMMAND sh -c "ar crsT libdpdks.a ./librte*.a"WORKING_DIRECTORY ${LIBDPDK_LIBDIR}COMMENT "Compressing static libraries"
)find_library(M_LIB m)
add_library(libdpdk STATIC IMPORTED GLOBAL)
add_dependencies(libdpdk compress_dpdk_libraries)
set_target_properties(libdpdk PROPERTIESIMPORTED_LOCATION ${M_LIB}INTERFACE_LINK_LIBRARIES "-Wl,--whole-archive;${LIBDPDK_LIBDIR}/libdpdks.a;-Wl,--no-whole-archive;rt;m;numa;fdt;atomic;mlx5;ibverbs;crypto;z;jansson;mlx4;pcap;isal;elf;pthread;dl;bsd"
)add_executable(${PROJECT_NAME} basicfwd.c)
target_link_libraries(${PROJECT_NAME} PRIVATE libdpdk)
多台虚拟机之间组网。
上面是在一台虚拟机中进行组网测试。如果不想这么做,想让两台虚拟机之间的网卡通过网桥互连。可以参考下面的做法(应该可行,但是我没测试过):不同组的网卡使用不同名称的网络适配器机进行网络隔离。
- 在VirtualBox上搭建DPDK数据包转发运行环境 - 黑牛2008的个人空间 - OSCHINA - 中文开源技术交流社区
- dpdk l3fwd/l2fwd实验-CSDN博客
- 2.VMware三种网络模式 - certainTao - 博客园
相关文章:

dpdk网络转发环境的搭建
文章目录 前言ip命令的使用配置dpdk-basicfwd需要的网络结构测试dpdk-basicfwddpdk-basicfwd代码分析附录basicfwd在tcp转发时的失败抓包信息DPDK的相关设置 前言 上手dpdk有两难。其一为环境搭建。被绑定之后的网卡没有IP,我如何给它发送数据呢?当然&a…...

【MYSQL】存储引擎MyISAM和InnoDB
MYSQL 存储引擎 查看MySQL提供所有的存储引擎 mysql> show engines; mysql常用引擎包括:MYISAM、Innodb、Memory、MERGE 1、MYISAM:全表锁,拥有较高的执行速度,不支持事务,不支持外键,并发性能差&#x…...

什么是DOM?(JavaScript DOM是什么?)
1、DOM简洁 DOM是js中最重要的一部分,没有DOM就不会通过js实现和用户之间的交互。 window是最大的浏览器对象,在它的下面还有很多子对象,我们要学习的DOM就是window对象下面的document对象 DOM(Document Object Model)…...

UIElement编辑器扩展 组件 Inspector
UIElement编辑器扩展 组件 Inspector https://docs.unity.cn/cn/2021.3/Manual/UIE-create-a-binding-uxml-inspector.html 简单开始 声明序列化VisualTreeAsset [SerializeField] VisualTreeAsset visualTree; 声明完,直接在脚本的Inspector面板,把你…...

Flask 3.x log全域配置(包含pytest)
最近使用到flask3.x,配置了全域的log,这边记录下 首先需要创建logging的配置文件,我是放在项目根目录的, Logging 配置 logging.json {"version": 1, # 配置文件版本号"formatters": {"default&qu…...

枚举算法(穷举法)(暴力法)
1.什么是枚举 枚举是指在一定范围内将所有情况一一列举,再通过条件判断得到自己想要的答案; 2.枚举核心 3.使用枚举的基本步骤 4.例题 4.1.我国古代数学家张丘建在他的《算经》一书中提出了著名的“百钱买百鸡”问题:鸡翁一值钱五;鸡母一值钱三;鸡雏三…...

计算机网络学习The next day
在计算机网络first day中,我们了解了计算机网络这个科目要学习什么,因特网的概述,三种信息交换方式等,在今天,我们就来一起学习一下计算机网络的定义和分类,以及计算机网络中常见的几个性能指标。 废话不多…...

ffmpeg中AVFrame解码linesize确定
一 测试环境 机型:Intel(R) Xeon(R) Gold 5218 ffmpeg版本4.3-dev 解码视频分辨率 720x1280 , 解码后 AVFrame linesize 768 解码视频分辨率 480x640, 解码后AVFrame linesize 512 二 linesize计算过程 avcodec_default_get_buffer2 -->update_frame_pool() --&g…...

数据可视化 | 期末复习 | 补档
文章目录 📚介绍可视化🐇什么是可视化🐇科学可视化,信息可视化,可视分析系统三者之间有什么区别🔥🐇可视化的基本流程🐇可视化的两个基本设计原则🐇数据属性🐇…...

【Docker】使用Docker安装Nginx及部署前后端分离项目应用
一、Nginx介绍 Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。它是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,公开版本1.19.6发布于2020年12月15日。其将源代码以类BSD许可证的形式发布,因它…...

28、web攻防——通用漏洞SQL注入HTTP头XFFCOOKIEPOST请求
文章目录 $_GET:接收get请求,传输少量数据,URL是有长度限制的; $_POST:接收post请求; $_COOKIE:接收cookie,用于身份验证; $_REQUEST:收集通过 GET 、POST和C…...

c++:类和对象(1),封装
C面向对象的三大特性:封装、继承、多态。 封装 封装的意义一: 将属性和行为作为一个整体,表现生活中的事物将属性和行为加以权限控制 类中的属性和行为,我们统一称为成员 属性也叫: 成员属性 成员变量 行为也叫&a…...

三、安全工程—安全架构(CISSP)
目录 一、安全工程 1.企业安全架构与系统安全架构 2.通用企业架构框架 2.1 Zachman框架...

Linux:shell脚本:基础使用(9)《数组》
数组就是一组数据类型相同集合 定义 数组名(元素内容…………) 如果没有元素内容就是空 arr1() # 定义了一个空数组 arr2(1 2 3 4 5 6 ) # 定义了一个元素是整形的数组 arr3("hello" "world" "你好" "世界") # 定义了一个元素为字符…...

TCP高并发服务器简介(select、poll、epoll实现与区别)
select、poll、epoll三者的实现: select实现TCP高并发服务器的流程: 一、创建套接字(socket函数):二、填充服务器的网络信息结构体:三、套接字和服务器的网络信息结构体进行绑定(bind函数&…...

Linux中的软件包管理器yum
目录 1.什么是软件包 2.关于 rzsz 3.查看软件包 4.如何安装软件 5.如何卸载软件 1.什么是软件包 ● 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. ● 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理…...

如何使用支付宝沙箱环境本地配置模拟支付并结合内网穿透远程调试
文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂ÿ…...

解决子元素的click事件会触发父元素的dbclick事件
解决子元素的click事件会触发父元素的dbclick事件 方案一:方案二:方案三:方案一方案二综合案例如下: 方案一: 错误思路:通过阻止子元素click事件的冒泡,阻止父元素的dbclick 正确思路ÿ…...

算法训练营Day38(动态规划1)
动态规划理论基础 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 区别 动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心&…...

基于Harris角点的多视角图像全景拼接算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 Harris角点检测 4.2 图像配准 4.3 图像变换和拼接 4.4 全景图像优化 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 function [ImageB…...

数学建模--PageRank算法的Python实现
文章目录 1. P a g e R a n k PageRank PageRank算法背景2. P a g e R a n k PageRank PageRank算法基础2.1. P a g e R a n k PageRank PageRank问题描述2.2.有向图模型2.3.随机游走模型 3. P a g e R a n k PageRank PageRank算法定义3.1. P a g e R a n k PageRank PageRank…...

samba服务搭建,并将共享目录映射到windows
系统版本:centos7 1、centos 安装samba yum -y install samba 2、查看安装信息 rpm -qa |grep samba 3、设置开机自启动 systemctl enable smb.service systemctl enable nmb.service 4、设置samba服务器配置文件 sudo vi /etc/samba/smb.conf 注意&#…...

golang 中使用 statik 将静态资源编译进二进制文件中
现在的很多程序都会提供一个 Dashboard 类似的页面用于查看程序状态并进行一些管理的功能,通常都不会很复杂,但是其中用到的图片和网页的一些静态资源,如果需要用户额外存放在一个目录,也不是很方便,如果能打包进程序发…...

北京住总集团携手云轴科技ZStack获行业云平台领航者创新实践奖
为进一步促进行业企业上云、用数、赋智发展,落实国家政策,加速云计算应用从互联网拓展至政务、金融、交通、电信等行业,推动以云计算为核心的数字产业创新,1月18日中国信息通信研究院主办的“企业上云用云专项行动会—行业云平台研…...

【漏洞攻击之文件上传条件竞争】
漏洞攻击之文件上传条件竞争 wzsc_文件上传漏洞现象与分析思路编写攻击脚本和重放措施中国蚁剑拿flag wzsc_文件上传 漏洞现象与分析 只有一个upload前端标签元素,并且上传任意文件都会跳转到upload.php页面,判定是一个apache容器,开始扫描…...

Buttton样式设置background属性失效的问题
最近遇到一个之前没有遇见的问题,就是在添加Button控件的时候发现对其设置background时没有效果,原因是AndroidStudio升级后默认按钮就是主题色,一个比较简单的方法是将Button改为android.widget.Button,对比效果如下:…...

使用vue-pdf插件加载pdf
安装: // 安装这个版本,其它版本会有千奇百怪的错,这个版本和4.0.0都是可以的 cnpm install vue-pdf4.2.0// 安装pdfjs-dist cnpm install pdfjs-dist2.5.207 使用: // 我的css样式是pxToRem,友友们使用可能样式会有…...

BP蓝图映射到C++笔记1
教程链接:示例1:CompleteQuest - 将蓝图转换为C (epicgames.com) 1.常用的引用需要记住,如图所示。 2.蓝图中可以调用C函数,也可以实现C函数 BlueprintImplementableEvent:C只创建,不实现,在蓝图中实现 B…...

龙芯+RT-Thread+LVGL实战笔记(30)——电子琴演奏
【写在前面】正值期末,笔者工作繁忙,因此本系列教程的更新频率有所放缓,还望订阅本专栏的朋友理解,请勿催更。笔者在此也简要声明几点: 有些硬件模块笔者并没有,如LED点阵、压力传感模块、RFID模块等,因此这些模块的相关任务暂时无法给出经过验证的代码。其实,教程进行…...

Python Process创建进程(2种方法)详解
虽然使用 os.fork() 方法可以启动多个进程,但这种方式显然不适合 Windows,而 Python 是跨平台的语言,所以 Python 绝不能仅仅局限于 Windows 系统,因此 Python 也提供了其他方式在 Windows 下创建新进程。 Python 在 multiproces…...