P4语言详解

P4语言详解,第1张

P4语言详解

p4c是一款 p4编译器。BMv2是支持P4编程的软件交换机。PI是P4 runtime的实现,用于Control Plane对数据平面的控制。mininet的功能是构建一个虚拟的网络拓扑。 它通过linux内核的一些特性(net命名空间),在一个主机上划分出多个虚拟网络空间,各个网络空间之间相互隔离,有自己的端口, ip等等。mininet让一个或者多个vhost(虚拟主机), 软件交换机(如ovs, bmv2)等 以进程的状态分别绑定在这些网络空间之中,共同构成一个进程级别的虚拟网络拓扑。需要注意的是这些进程级别的主机和交换机他们只是网络上的隔离,而文件系统则是共享主机的文件系统。p4 tutorials 提供了用于学习的实例代码,它提供了很多个带有方向性的实际场景,例如负载均衡,简单的隧道机制,源路由等。并且它事先写好了控制面代码,让p4的初学者可以集中注意力在数据面编程的学习之上。scapy是一个python库,提供构建数据包,抓包,解析包等功能。它功能强大,但是效率很低。由于P4编程中经常会引入各种各样的数据包,有些甚至是开发者自定义的数据包格式。所以我们可以利用scapy进行便捷的组包,发包。如果需要高速率的发包和解析包就不能使用scapy了。

P4
├── behavioral-model  ## BMv2 软件交换机
├── grpc              ## 作为BMv2的依赖
├── mininet           ## mininet 网络仿真
├── p4c			      ## p4c 编译器
├── PI                ## PI P4 runtime库
├── protobuf          ## 作为依赖
└── tutorials         #### 教程目录,以及以后主要的学习,实验
tutorials/
├── exercises   # 存放各种练习
├── utils       # 工具脚本目录
└── vm          # 用于vagrant构建虚拟机的目录,可以无视

其中utils里面存放了一些用于调用各个组件(mininet, bmv2, PI, p4c)的脚本,有了这些脚本,我们可以专注于p4代码的开发,控制面的编写,以及拓扑的构建,而不需要费神去了解bmv2的启动命令,p4c的调用选项等等。具体如何使用,也是非常的简单,我们进入一个具体的例子查看:

# 我们切换进入 exercises/basic 这个例子
basic
├── basic.p4   # 要编写的p4代码
├── build      # 生成文件的目录
├── logs       # 日志文件, 在调试的时候真的非常重要!
├── Makefile   ### 通过Makefile 来调用utils下的脚本!
├── pcaps      # 生成的pcap包,可以使用wireshark等工具来分析
├── README.md  # 详细的指导
├── receive.py ## 利用scapy写的抓取和分析数据包的工具
├── s1-runtime.json  #
├── s2-runtime.json  # 在运行同时加载入交换机的控制面代码,这里有争议,稍后再谈
├── s3-runtime.json  #
├── send.py    ## 利用scapy写的构建和发送数据包的工具
├── solution   # 这里有这个例子的示例代码(答案)
└── topology.json  # 描述拓扑的json文件

可以看到,通过Makefile,我们可以调用utils下的脚本,让我们的p4代码跑起来:

make run  # 启动命令
### ...启动过程中的输出
 
mininet>  # mininet 命令行
### ... 你的一些实验 *** 作
mininet> exit  # 退出mininet 命令行
make clean # 清理上次运行留下的缓存文件和遗留的进程,重要,否则下次运行会可能使用旧的代码。

调用make run,我们可以运行当前目录下(以basic目录为例)的代码,它将执行以下几个步骤:

编译basic.p4 代码,生成basic.json解析topology.json, 并且构建相应的mininet仿真拓扑,按照该拓扑启动一台或者多台BMv2交换机,以及一些host启动BMv2的同时会将p4代码编译产生的json文件导入启动BMv2后会解析 sN-runtime.json 文件,将其载入 交换机sN流表之中进入mininet命令行,同时开始记录log以及搜集pcap文件

V1Switch(
MyParser(),    // 解析数据包,提取包头 
MyVerifyChecksum(),  // 校验和验证
MyIngress(),   // 输入处理
MyEgress(),    // 输出处理
MyComputeChecksum(),  // 计算新的校验和
MyDeparser()   // 逆解析器
) main;

我们要需要完成以下几个基本的步骤,其余部分可以暂时省略。

定义相关数据结构:根据需求,我们需要定义 ipv4数据包头以及其下层的以太网包头结构。解析数据包:我们在此提取ipv4包头。MyIngress:得到了数据包头,我们定义一个用于转发的流表,然后定义匹配域和动作。MyDeparser:逆解析器写好控制面代码

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5714867.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存