本文主要是介绍# P4 Tutorial 快速上手 (4) P4Runtime,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
P4 Tutorial 快速上手 (4) P4Runtime
提示:本系列仅适用于软件交换机BMv2
P4 Tutorial 快速上手系列 (1)
P4 Tutorial 快速上手系列 (2)
文章目录
- P4 Tutorial 快速上手 (4) P4Runtime
- 简介
- P4Runtime协议是?
- Exercises说明
- mycontroller.py
- 测试
- 总结
- 附录
简介
代码库链接:https://github.com/p4lang/tutorials/tree/master/exercises/p4runtime
为了介绍用于向P4交换机下发策略的P4Runtime协议,官方教程中提供了基于Python的简易控制器(位于tutorials/utils/p4runtime_lib),并提供了相应的练习帮助理解。因此,本节围绕exercises中p4runtime进行说明,该练习所使用的P4程序为advanced_tunnel.p4,与之前的教程不同,该练习中P4文件已经被修改完善。其在上一篇中的basic_tunnel.p4的基础上增加了在交换机内部添加隧道头、按隧道转发与删除隧道头功能,读者需要对mycontroller.py进行修改,将缺少的流表规则下发到交换机中并远程监测交换机的计数器状态。
P4Runtime协议是?
P4Runtime是一组控制平面规范,是基于Protobuf以及gRPC框架的协议,用于控制由 P4 程序定义的设备或程序的数据平面实体。图 1 表示 P4 运行时参考体系结构。逻辑上,控制器位于顶部,转发设备或目标位于底部。P4Runtime 仅为每个读/写实体授予对单个主控制器的写入访问权限。P4Runtime 允许每个角色使用一个主控制器,并且基于角色的客户端仲裁方案确保只有一个控制器对每个读/写实体或管道配置本身具有写访问权限。任何控制器都可以对任何实体或管道配置执行读取访问。关于P4Runtime API的介绍可以在此处找到:P4Runtime Specification
Exercises说明
该练习需关注的文件包括advanced_tunnel.p4与mycontroller.py。
在P4源程序中,首先,在Ingress中添加了两个计数器用于监测以网内隧道转发的数据包个数:
counter(MAX_TUNNEL_ID, CounterType.packets_and_bytes) ingressTunnelCounter;
counter(MAX_TUNNEL_ID, CounterType.packets_and_bytes) egressTunnelCounter;
其次,增添了两个action:
action myTunnel_ingress(bit<16> dst_id) {hdr.myTunnel.setValid();hdr.myTunnel.dst_id = dst_id;hdr.myTunnel.proto_id = hdr.ethernet.etherType;hdr.ethernet.etherType = TYPE_MYTUNNEL;ingressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id);}
action myTunnel_egress(macAddr_t dstAddr, egressSpec_t port) {standard_metadata.egress_spec = port;hdr.ethernet.dstAddr = dstAddr;hdr.ethernet.etherType = hdr.myTunnel.proto_id;hdr.myTunnel.setInvalid();egressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id);}
对于myTunnel_ingress,其为数据包增添了隧道包头,并希望根据流表规则插入目的地id(dst_id)。与之相反的是myTunnel_egress,在删除隧道包头的同时修改目的地mac地址。值得一提的是counter的用法,计数器将对对应索引地址计数。
在简易控制器mycontroller.py中,首先需要注意的是导入的包。
import p4runtime_lib.bmv2
import p4runtime_lib.helper
from p4runtime_lib.switch import ShutdownAllSwitchConnections
Lib文件夹位于tutorials/utils/p4runtime_lib中(后续若改用高级控制器可以略过),包括了一些用于控制数据平面的工具库,上述代码中涉及到bmv2.py/helper.py/switch.py三个文件。其中,helper.py主要负责与P4info文件的交互,switch.py主要负责对交换机的一系列操作(连接/读写流表等)。
教程重点在于使用该简易控制器体验实际的控制平面与数据平面的交互流程。
mycontroller.py
程序的主函数首先对P4info和json文件的检查,然后执行main()程序。main()程序逻辑如下:
- 连接交换机s1和s2
- 成为si和s2的主控制器
- 安装P4info与json文件
- 将隧道规则写入s1和s2流表
- 读取s1和s2的流表规则(记得取消注释)
- 每2秒统计一次各交换机ingress和egress计数器的值
- 当程序结束市会断开与所有交换机的连接
其中第4步中writeTunnelRules()与第5步readTableRules()是不完整的,需要对其进行修改,其中用到的方法均在tutorials/utils/p4runtime_lib/helper.py文件中。
对于方法writeTunnelRules(),需要补充安装transit tunnel表项的程序段,仿照其他tunnel表项的插入程序即可:
table_entry = p4info_helper.buildTableEntry(table_name="MyIngress.myTunnel_exact",match_fields={"hdr.myTunnel.dst_id": tunnel_id},action_name="MyIngress.myTunnel_forward",action_params={"port": SWITCH_TO_SWITCH_PORT})ingress_sw.WriteTableEntry(table_entry)print("Installed transit tunnel rule on %s" % ingress_sw.name)
注意advanced_tunnel.p4定义的动作myTunnel_forward只需要一个端口参数,由于是在交换机间传输,选择topology.json所设置的端口2即可(s1端口2与s2端口2相连接),mycontroller.py在程序第十九行定义了SWITCH_TO_SWITCH_PORT=2,直接使用即可(方便理解程序)。
对于方法readTableRules(),其目标是从返回的报文解析出想要的表项信息,例如表的名字,匹配域的名字和值,动作的名字和值等,同样需要用到helper.py中get开头的方法。
for response in sw.ReadTableEntries():for entity in response.entities:entry = entity.table_entry# TODO For extra credit, you can use the p4info_helper to translate# the IDs in the entry to namestable_name = p4info_helper.get_tables_name(entry.table_id)print('%s: ' % table_name, end=' ')for m in entry.match:print(p4info_helper.get_match_field_name(table_name, m.field_id), end=' ')print('%r' % (p4info_helper.get_match_field_value(m),), end=' ')action = entry.action.actionaction_name = p4info_helper.get_actions_name(action.action_id)print('->', action_name, end=' ')for p in action.params:print(p4info_helper.get_action_param_name(action_name, p.param_id), end=' ')print('%r' % p.value, end=' ')print()
这里需要注意程序段首先调用了switch.py的ReadTableEntries()方法以获取table_id,基于helper.py的注释可以知道通过get_tables_name获取表名,以供其他get_……方法传参,从而print表项。
测试
该部分测试参照README.md即可
总结
以上就是本系列(4)的主要内容,该教程由于涉及控制平面与数据平面交互,并且使用的是教程制作者提供的lib库,较之前的教程更为复杂,主要是感受使用P4runtime协议完成从上至下的控制,后续建议使用成熟的商业网络控制器(e.g. ONOS/ODL)。
附录
mycontroller.py完整程序
这篇关于# P4 Tutorial 快速上手 (4) P4Runtime的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!