P4语言学习-环境配置+源码学习(1)

时间:2024-04-08 08:31:48

P4语言学习-源码阅读(1)

本文是本人学习p4语言的时候阅读的源码,将学习步骤写下来作为记录。本文是主要基于www.github.com/p4lang/tutorials/examples/copy_to_cpu中的内容。
主要内容如下:

  • 配置P4语言的运行环境
  • 让一个Demo运行起来

首先在浏览器中输入www.github.com/p4lang/tutorials,我们可以看到tutorials文件夹目录如下:
P4语言学习-环境配置+源码学习(1)

首先我们来看看README.md文件内容。
P4语言学习-环境配置+源码学习(1)
大概意思就是编辑env.sh文件来指向你本地复制下来的bmv2和p4c-bm文件,我们先来看看env.sh里面有什么东西?之后再来看看,如何正确配置P4语言的环境。
下面来看env.sh文件中的内容
首先,.sh文件是脚本文件,类似于windows中的批处理文件,总的来说可以做一些事情,我们看一下env.sh文件的名字,env,猜测是和配置环境变量相关的。
接下来打开env.sh文件看看里面有什么内容?

P4语言学习-环境配置+源码学习(1)
短短几行代码,到底写了些什么?
第一行:
里面使用了cd和pwd命令,cd命令是切换到某一个目录下面,pwd命令是用来查看当前工作目录的完整路径。cd和pwd命令之间有一个&&,&&是指在很多情况下,很多指令想一次输入然后执行,而不想分次执行,这时就要用到&&和||了,比如说cmd1 && cmd2,表达了下面的一些语意:
若cmd1执行完毕且执行正确,则开始执行cmd2。
若cmd1执行完毕且执行错误,则不执行cmd2。
我们在第一句代码中也可以看到BASHSOURCE[0]liunx使{}进行变量替换,而BASH_SOURCE[0]等价于BASH_SOURCE,是当前执行的shell文件所在的路径及文件名。
所以第一行代码,就是拿到当前脚本文件所在的路径,使用cd转到这个目录下面。
第四行:
取THIS_DIR中的值,附上bmv2,将它给BMV2_PATH
第六行:
取THIS_DIR中的值,附上p4c-bm,将它给P4C_BM_PATH
接下来,来看看如何配置P4语言的环境,请点击tutorials下的README.md文件中的here链接。
P4语言学习-环境配置+源码学习(1)
下面来看看如何配置自己的P4语言环境:
首先需要下载2个github上的repositories,并且需要安装他们的依赖。使用以下命令进行repositories的下载:
P4语言学习-环境配置+源码学习(1)
第一个repository(bmv2)是行为模型的第2个版本,这是一个用c++语言编写的软件交换机,这个交换机的行为是由你编写的P4程序决定的。
第二个repository(p4c-bm)是行为模型的编译器,它的输入是P4语言,输出是一个JSON文件,这个文件可以被加载到bmv2(软件交换机)上。
这两个repository都需要安装依赖(dependencies),p4c-bm是用python写成的repository,需要安装所需的python依赖,使用以下命令进行安装:
P4语言学习-环境配置+源码学习(1)
bmv2是一个用c++写成的repository,需要很多外部的依赖,这些依赖列举如下:
P4语言学习-环境配置+源码学习(1)
如果你运行的是ubuntu 14.04+以上的操作系统,这些依赖可以被轻松的安装,使用bmv2文件夹中的install_deps.sh脚本进行安装。
现在我们看一下bmv2中是否有这个脚本
P4语言学习-环境配置+源码学习(1)
我们确实发现了这个脚本,那么如何使用这个脚本呢?
首先假如脚本文件放置在/home/aaa/xxx.sh这里,先使用cd到这个目录下,然后使用sudo ./xxx.sh回车来运行脚本。同样也可以使用sudo+脚本文件的绝对路径来运行脚本。

当所有的依赖都安装好了之后,输入以下代码:
P4语言学习-环境配置+源码学习(1)

除此之外,还需要安装mininet,而且还需要安装python packet,使用以下代码进行安装:
P4语言学习-环境配置+源码学习(1)
经过上面的步骤,P4语言的环境就配置好啦。
在开始运行例子之前,我们还需要告知你将bmv2和p4c-bm的repository克隆到哪了,请更新shell中的BMV2_PATH和P4C_BM_PATH这两个变量(注意,这两个变量之前在之前的env.sh脚本中出现,env.sh在这个repository的根目录下,即tutorials目录下)。
注意:如果你把这两个repository和tutorials克隆到同一个目录下(即三个目录之间是平行关系),那么就不需要改变变量的值了。

接下来,来看看p4lang/tutorials/examples文件夹的内容。

P4语言学习-环境配置+源码学习(1)
首先还是阅读一下README.md文件的内容
examples目录下包括了P4的代码例子,可以运行在bmv2(软件交换机)上,这些例子说明了P4很多先进的特性,例子有以下几个
P4语言学习-环境配置+源码学习(1)
copy_to_cpu:接受packet,封装packet,并将packet发送到指定的port
meter:使用P4中间接的meter
TLV_parsing:解析IPV4
register:使用P4中的register,从控制平面上读取状态
counter:使用P4中的counter
action_profile:使用P4中的action profile,使用ECMP 作为支持
resubmit:重发packet到ingress pipeline
simple_nat:一个TCP中full-cone NAT的基本实现
P4语言学习-环境配置+源码学习(1)
上面的图片说的还是配置P4语言环境的事情,步骤和前面类似,只有最后一句话不同,配置完环境后,还需要运行veth_setup.sh脚本(在examples目录下)去设置switch需要的interface。

接下来,读tutorials/examples/copy_to_cpu目录下的内容
P4语言学习-环境配置+源码学习(1)
按照管惯例,还是先读README.md文件。
首先根据上面的内容,我们知道了copy_to_cpy做了一件事情:接受packet,封装packet,发送packet到指定的端口
将下来,来读README.md文件内容。
这个程序尽可能简单地说明如何发送一个packet向CPU,这个程序做以下的事情:
(1)clone_ingress_pkt_to_egress action,将incoming packet映射到cpu的端口
(2)映射到CPU的packet被封装到一个自定义的cpu_header中,cpu_header中包含两个field:device和reason,device是1个字节,设置为0,reason是1个字节,被设置为0xab
(3)原始的packet在出口处egress pipeline被扔掉
也就是说,这个程序接受了一个packet,然后将它包装一下,然后交给出口。
Running the demo
我们提供了一些范例,让你可以测试这个程序,由以下脚本组成:
P4语言学习-环境配置+源码学习(1)
run_switch.sh:编译P4程序,并且启动switch
receive.sh:嗅出port 3中的packet,并且打印出packet的十六进制。
send_one.py:从port 0 发送一个简单的ipv4 packet

To run the demo:
P4语言学习-环境配置+源码学习(1)
首先输入:
cd到demo所在的目录下
输入sudo ./run_switch.sh
P4语言学习-环境配置+源码学习(1)
输入sudo python receive.py启动一个listener。在没发送前,监听器的页面为空。当一旦使用send_one.py,监听器的界面立马出现一些数据。
P4语言学习-环境配置+源码学习(1)
输入sudo python send_one.py发送数据
P4语言学习-环境配置+源码学习(1)

好了,这个Demo已经可以运行起来了,这篇文章就到此结束吧。源码分析放到下一篇文章中。


后记

因为自己也是刚开始接触linux和github,有点茫然,所以决定一笔一划地将自己学习过程记录下来。虽然慢,但是也不再茫然。