尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

P4开发环境搭建全攻略:p4c+bmv2+protobuf+thrift版本兼容实践

P4开发环境搭建全攻略:p4c+bmv2+protobuf+thrift版本兼容实践 简介面向P4可编程数据平面开发者的环境配置安装包针对P4工具链依赖复杂、安装步骤繁琐、版本兼容性差等问题集成了多个核心组件。包内包含behavioral-model即bmv2软件交换机、p4cP4编译器、protobuf 3.2.0以及thrift 0.9.2等关键依赖可支撑从P4源程序编写、编译到模拟运行的全流程帮助开发者快速搭建可用的P4开发与实验环境。资源采用.gz格式压缩整体大小约147.8MB便于一次性下载部署。目前已有608人学习下载适用于网络方向的高校学生、科研人员以及初步接触P4编程的技术爱好者。借助该资源包可免去逐个寻找安装包、手工匹配版本与编译依赖的繁琐过程显著提升环境搭建效率从而更专注于P4数据平面编程与实验验证本身。 搭建P4开发环境这件事说难不难但确实烦。尤其是第一次接触P4的人光是搞清楚p4c、behavioral-model、protobuf、thrift这一堆组件之间的关系就得耗掉不少时间。我当初配置这套环境时在版本兼容性上踩了不少坑所以这次把一套亲测可用的安装包组合behavioral-model gmock-1.7.0 p4c protobuf-3.2.0 thrift-0.9.2完整梳理出来希望能帮你省下那些无谓的折腾。这套环境解决的核心问题是让P4程序能够在本地完成“编写—编译—仿真运行”的闭环。P4本身是一门数据平面编程语言写完的代码不能直接跑在真实交换机上需要p4c把它编译成特定目标平台的配置再由behavioral-model也就是bmv2提供一个软件交换机来模拟运行。而protobuf和thrift在这套体系里的角色是负责RPC通信和数据序列化——简单说就是让控制平面和BMv2之间能高效、规范地交换信息。gmock则是测试用的在开发BMv2的C代码时非常有用。这套环境适合谁如果你是做P4数据平面开发、SDN控制器与交换机联调、或者研究可编程网络协议解析的人那这套配置几乎是必需品。哪怕是刚入门P4的新手把这套环境跑通也等于完成了最艰难的前50%。1. 环境组件解析每样东西为什么非它不可在动手安装之前我建议你先搞明白这些组件各自解决什么问题。这不是为了凑字数而是因为P4的依赖关系比较绕很多人装到一半卡住往往就是没搞懂组件的边界和版本约束。1.1 P4C把P4代码翻译成目标配置的编译器P4C是P4语言的前端编译器也是整套环境里最核心的组件。它做的事情是把你写的P4-16代码解析成中间表示IR然后再根据不同的后端目标生成对应的JSON配置或特定硬件平台的表项配置。在bmv2这套软件交换机体系里p4c生成的JSON文件就是behavioral-model运行时的“程序”。p4c本身是基于C开发的编译它需要一整套工具链和依赖库。如果你在安装过程中碰到类似“Could not find a package configuration file provided by P4C”的错误通常就是依赖没装全或者是编译器版本过高导致兼容性问题。我建议在Ubuntu 18.04或20.04这类长期支持版本上操作能减少很多不必要的麻烦。1.2 Behavioral-ModelP4程序的家用模拟器Behavioral-Model俗称bmv2是一个用C实现的软件交换机专门用来模拟P4定义的数据平面行为。它有点像一个虚拟机你给它一个由P4程序编译出来的JSON配置它就可以模拟报文从入口端口到出口端口经历的所有匹配-动作流程。BMv2本身支持多种“目标”比如simple_switch、simple_switch_grpc、psa_switch等。其中simple_switch是最基础的版本适合学习调试simple_switch_grpc则集成了gRPC和P4Runtime接口适合做控制平面联调。你自己的需求如果只是验证P4逻辑用simple_switch就够如果要做SDN控制器的对接实验那建议加上grpc版本。1.3 Protobuf和Thrift通信与序列化的地基这两个库经常被初学者忽略但它们的版本选择直接决定整套环境能否编译通过。Protobuf是Google的序列化库BMv2的P4Runtime实现依赖它来定义和交换结构化数据。你给出的版本是protobuf-3.2.0这是一个兼顾稳定性和兼容性的版本比它更新的3.5以上版本会和某些旧版gRPC产生冲突比它更旧的版本则缺少一些必要接口。Thrift是Facebook开源的RPC框架在BMv2里主要用于internal RPC的通信。thrift-0.9.2这个版本和BMv2的代码契合度很高如果你擅自升级到0.11以上的版本很可能会遇到函数签名变更导致的编译错误。所以这套组合里thrift的版本不要轻易动。1.4 GMock测试框架里的辅助角色GMock是Google Test配套的C mock框架主要用于单元测试中对依赖对象的模拟。在BMv2的Utest目录下不少测试用例需要链接GMock。如果你不打算跑BMv2的C单测其实可以不装它但既然这套安装包里已经包含那就顺手装上后面做二次开发或跑自带测试时都用得上。2. 环境准备与依赖安装提前扫平90%的坑这个环节我放在前面是因为很多人在安装protobuf或p4c时才发现系统缺了一堆基础依赖然后中途停下来去补装打乱了节奏。按照下面这些步骤提前准备好后续基本可以一路畅通。2.1 系统要求与基础工具链建议在64位Ubuntu 18.04 LTS或20.04 LTS上操作。其他发行版理论上也能跑但如果你不太熟悉Linux编译环境就老老实实用Ubuntu。基础工具链一句话执行即可sudo apt-get update sudo apt-get install -y build-essential cmake git python3 python3-pip这里我要提醒一点不要用系统自带的cmake旧版本。Ubuntu 18.04自带的是cmake 3.10对于p4c的一些子模块来说版本偏低建议用pip安装新版cmakepip3 install cmake装完后确认一下cmake版本最好是3.16以上。2.2 P4C的专属依赖库P4C的编译额外需要以下库sudo apt-get install -y g git automake libtool libgc-dev bison flex libfl-dev libgmp-dev libboost-dev libboost-iostreams-dev libboost-graph-dev llvm pkg-config python3-setuptools这里面有几个值得单独说两句libgc-dev是Boehm垃圾回收器p4c在处理大型P4程序时靠它管理内存不装会直接编译报错bison和flex是生成解析器用的版本太旧也会出问题。libboost系列则用来支持p4c中核心的数据结构最好一次性装全。3. 核心组件编译安装实录下面进入真正的实操环节。我按照“先底层、后上层”的顺序来安装即先装protobuf和thrift再装p4c最后装BMv2。这个顺序是经过多次失败后总结出来的——因为上层组件编译时依赖底层库的头文件和库文件顺序反了会反复出现“找不到头文件”的尴尬。3.1 编译安装protobuf-3.2.0进入源码目录后依次执行标准三步cd protobuf-3.2.0 ./autogen.sh ./configure --prefix/usr make -j4 sudo make install sudo ldconfig关于--prefix/usr我多说两句。默认安装路径是/usr/local在大多数情况下这么装也没问题。但如果你后面编译p4c时出现找不到protobuf头文件的情况就很可能是路径没被搜索到。直接装到/usr下可以让/usr/include和/usr/lib这两个默认搜索路径直接覆盖到省去一堆环境变量配置。编译时用-j4还是-j8取决于CPU核心数。如果内存小于8G建议老老实实用make -j2否则编译过程中内存耗尽直接卡死别再问我怎么知道的。3.2 编译安装thrift-0.9.2thrift的编译步骤与protobuf类似但它默认会尝试编译所有语言绑定包括Java、Python、PHP等这不仅慢而且某些绑定依赖额外库导致编译失败。我建议只保留C和Python绑定cd thrift-0.9.2 ./configure --prefix/usr --without-java --without-php --without-perl --without-nodejs --without-lua --without-ruby --without-erlang --without-go --without-haskell make -j4 sudo make install sudo ldconfig这里还有一个隐形坑thrift编译依赖libssl-dev和libboost-dev如果缺失会在make阶段报错。保险起见sudo apt-get install -y libssl-dev libboost-devthrift 0.9.2对编译器也比较挑如果你用的是GCC 9及以上版本可能会遇到“no matching function for call to”这类模板推导错误。遇到这种情况最简单的办法是安装GCC 8并切换过去sudo apt-get install -y g-8 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 80 sudo update-alternatives --install /usr/bin/g g /usr/bin/g-8 803.3 编译安装p4cp4c的编译依赖一个叫p4c-dpdk的子模块而且对protobuf的版本很敏感。在开始编译前先确保protobuf已经正确装好并且能用以下命令验证protoc --version正常情况下应显示libprotoc 3.2.0。确认无误后继续cd p4c git submodule update --init --recursive mkdir build cd build cmake .. make -j4 sudo make installp4c的编译时间比较长在性能一般的机器上可能要40分钟以上建议准备好咖啡。如果编译中报错最常见的集中在两个地方一是protobuf头文件找不到说明前面的安装路径有问题二是Boost库版本不匹配这通常是因为系统装了多个Boost版本导致链接错误可以用sudo apt-get purge libboost-all-dev清理后重新安装。另外注意p4c编译完成后可执行文件默认在build/p4c。为了方便调用建议把它软链到/usr/local/binsudo ln -s /usr/local/bin/p4c /usr/local/bin/p4c如果你的安装路径不是/usr/local按实际路径调整。3.4 编译安装behavioral-modelBMv2的编译是整个过程中最考验耐心的环节因为它对依赖的齐全度要求特别高。先把系统依赖补齐sudo apt-get install -y libreadline-dev libgmp-dev libpcap-dev libevent-dev然后进入BMv2源码目录同样需要初始化子模块cd behavioral-model git submodule update --init --recursive ./autogen.sh ./configure --enable-debug --with-pi --with-thrift make -j4 sudo make install--with-pi是启用P4Runtime支持的关键选项如果你需要对接ONOS或Ryu这类控制器一定得带上。如果不带这个参数编译出来的simple_switch是无法接收P4Runtime下发流的。编译成功后可以验证一下simple_switch --version能输出版本号说明BMv2的核心安装完成。完整安装还会在targets/simple_switch目录下生成二进制的simple_switch可执行文件。3.5 安装gmock-1.7.0GMock 1.7.0是一个比较老的版本但BMv2的Utest测试用例就是按这个版本写的用新版反而可能编译不过。编译链接方式如下cd gmock-1.7.0 ./configure make sudo make install装完后需要在BMv2的configure阶段让它找到gmock头文件和库文件。通常默认路径就能找到如果你自定义了安装路径可以通过环境变量补充export CPLUS_INCLUDE_PATH/usr/local/include:$CPLUS_INCLUDE_PATH export LIBRARY_PATH/usr/local/lib:$LIBRARY_PATH不过说句实在话如果你只是跑业务逻辑而不是做BMv2二次开发这步可以跳过。真到了需要运行BMv2自带单测时再补装也行。4. 常见错误与避坑手册这部分内容价值极高但如果踩过坑全都值回票价。我按出现频率排序把几个典型的错误和对应解法列出来。4.1 “fatal error: google/protobuf/xxx.h: No such file or directory”这个错误几乎九成是因为protobuf安装路径不是/usr导致的。解法第一优先重新安装protobuf时指定--prefix/usr第二也可以将/usr/local/include软链到/usr/include但这不推荐容易造成库混乱。4.2 “Could not find a package configuration file provided by P4C”这个多半是因为p4c没有正确安装完或者安装路径并未纳入cmake搜索范围。最简单的检查方式find / -name *p4c* 2/dev/null | head -20如果cmake还是找到不可以手动指定安装前缀在BMv2的configure步骤中加上./configure CXXFLAGS-I/usr/local/include LDFLAGS-L/usr/local/lib4.3 thrift编译报错“error: ‘uint32_t’ does not name a type”这是个典型的版本兼容问题clang或gcc新版才会出现。解决办法是在configure前加上环境变量CXXFLAGS-stdc11 ./configure ...4.4 BMv2运行时报“RuntimeError: P4Runtime requires gRPC”出现这个错说明BMv2的运行时(PI)和gRPC库没有链接上。检查是否安装了gRPC以及protobuf的grpc插件sudo apt-get install -y libgrpc-dev libgrpc-dev protobuf-compiler-grpc如果已经安装并依旧报错则需要在编译BMv2的configure阶段精确指定gRPC路径同时确保--with-pi参数已启用。4.5 环境配置临时变量让一切变得顺手安装全部完成后每次打开新终端可能需要刷新一下动态链接库以及PATHsudo ldconfig export PATH/usr/local/bin:$PATH为了避免反复输入建议把这行加到~/.bashrc里。当然如果你全部装到了/usr目录下这一步基本可以省掉。5. 一些值得尝试的验证用例环境配好后先用自带的示例程序验证一遍别急着上手写代码。可以在p4c源码目录下找到testdata/examples选一个简单例子编译运行p4c --target bmv2 --arch v1model --std p4-16 testdata/examples/simple_router.p4如果生成出了simple_router.json说明p4c工作正常。接着启动BMv2sudo simple_switch --log-console --dump-packet-data simple_router.json看到Switch was started字样就说明整套环境已经完全跑通。此时你可以用simple_switch_CLI手动下发表项开始真正的P4实验。写在最后这套环境的搭建本质上是在跟版本兼容性做博弈。放下来说每个组件单独装都不难难的是让它们协同工作。按我这套组合和顺序来操作可以少走很多弯路。我在多次配置中还发现一个小技巧在编译BMv2前先编译一次grpc和nlohmann/json库可以显著减少后续报错。具体做法是将nlohmann/json单头文件放入/usr/include/nlohmann/并在系统安装libgrpc后重新执行./configure --with-pi --with-thrift并 make clean 后再 make基本能一次通过。这套环境跑通之后你再回头去看P4的语法、v1model架构、P4Runtime的实现会发现理解起来轻松很多。毕竟有了能实际跑的环境很多概念才能真正落地。祝你配置顺利早日用P4写出你的第一个自定义转发逻辑。本文还有配套的精品资源点击获取
返回列表