介绍:
这次试验,我们用p4runtime发送flow entries到switch。
虚机安装参考:P4 Tutorial 安装
我们会用到basic_tunnel实验中的P4程序,将其重命名为advanced_tunnel.p4,然后增加两个counters(ingressTunnelCounter, egressTunnelCounter)和两个新的actions(myTunnel_ingress, myTunnel_egress)。
关于控制平面,P4程序只是定义包处理的pipeline,而table的rules是需要控制平面下发。在本次实验里,mycontroller.py将实现控制平面,这点和前两个basic实验有所不同。
简单来讲:一个.p4的文件会编译生成一个Info文件里面是含有table id等信息是控制平面下发具体规则的依据;再生成一个配置文件(格式根据target而定)下发数据平面作为包处理的pipeline。控制平面还通过p4runtime对数据平面管理。
步骤1:运行(不完整)代码
1sudo make run (编译advanced_tunnel.p4,启动mininet实例搭建拓扑,为hosts分配IP)
2.h1 ping h2,此时还不能正常通信
3.打开另一个终端,运行mycontroller.py。这将安装advanced_tunnel。p4在交换机上编程并加载tunnel ingress rules。该程序每2秒打印一次tunnel ingress 和 egres计数。您应该看到s1的tunnel ingress计数器在增加:
因为s1和s2之间的transit rules还没有,所以只能看到s1 进入隧道计数。
4.Ctrl-C 停止mycontroller.py,完成switches间的流量基于隧道ID转发的rules。打开mycontroller.py,完成TODO部分。
步骤2:开始实现隧道转发
mycontroller.py 是一个基础的控制平面,它会做以下操作:
1.为P4Runtime服务建立到switches的gRPC连接;
2.Pushes the P4 program to each switch.推送P4程序到每台switches;
3.为h1到h2间的两个隧道编写规则,h1到h2隧道ID 100,h2到h1隧道ID 200;
4.每2秒钟读取一次tunnel ingress和egress 的计数。
同样还是老套路替换TODO部分。
在mycontroller.py 中找到 writeTunnelRules函数中编写tunnel transit rule:匹配隧道ID并将数据包转发到下一跳。
修改前:
修改后:
在实验中,会使用p4runtime_lib下的一些类和方法:
helper.py
包含用于解析p4info文件的 P4InfoHelper 类。
提供实体名称与ID的转换方法。
构建P4Runtime table的P4程序相关部分。
switch.py
包含SwitchConnection类,该类获取gRPC客户端stub,并建立到交换机的连接。
提供helper方法,用于构造P4Runtime协议缓冲区消息并进行P4Runtime gRPC服务调用
bmv2.py
包含Bmv2SwitchConnection,它扩展了SwitchConnections,并提供BMv2特定的设备载荷以加载P4程序。
convert.py
提供便捷的方法,将friendly字符串和数字编码、解码成协议缓冲区消息所需的字节字符串。
Helper.py 使用
步骤3:运行解决方案
打开另一个终端执行python文件,控制平面会把rules下发到数据平面。这时会看到计数增长。
./my_controller.py
这时通过命令行登录s1,看下switch的转发规则如下:
- 目的IP10.0.2.2/32进行LPM匹配,送进隧道100(显示的64是十六进制)。
- 精确匹配隧道ID100,送到接口2。
- 隧道ID是200(显示c8是十六进制),封装08–0111的h1的Mac,送到接口1。