P4 Runtime是一套基于Protobuf以及gRPC框架上的协议,透过P4 Runtime.SDN控制器或是使用者可以控制支援P4的装置。
P4 Runtime目前是由P4 API Workgroup所制定,目前还在开发阶段,但大多数需要的功能已被支持,例如操作Table Entry或Action profile、查询Counter等等。
除了上述的特点以外,使用者或是控制器也可以透过P4 Runtime去修改装置上的pipeline,且p4 Runtime并不会因为装置上使用不同的P4配置而改变。
与OpenFlow不同的点除了具备高度弹性的讯息格式以外,控制器与装置之间连接的顺序也不一样,以往OpenFlow是需要由控制器开放特定接口,然后装置连接上控制器。
而P4 Runtime的设计则是在装置上开放gRPC server,由控制器连接装置,因此在装置上都会有一个代理人(Agent)负责处理由控制器来的连接。
P4 Runtime是透过一个protobuf档案所定义出来,我们可以在p4的官方的GitHub上找到相关的定义:
https://github.com/p4lang/PI/blob/master/proto/p4/p4runtime.proto
下图来自p4runtime.proto,这一份protobuf中定义了相关的讯息格式,举例来说,一个TableEntry包含了table_id,多个FieldMatch、TableAction、priority以及相关的metadata。
gRPC除了提供单方向的RPC界面以外,也提供双向的stream channel,举例来说有时候我们会希望switch做Packet-In/Out的动作,这部分就需要用到stream channel来操作,而 P4 Runtime也提供相关讯息格式供这类型的需求使用。
从上图中我们看到,当要对装置里面的咨询进行操作时,需要使用一个unsigned int类型的ID而非名称,名称与ID对应关系必须透过读取P4 Info设定档来获得。
原则上在编译阶段,前端的编译器(front-end compiler)除了将原始的P4档案编译成中间码(IR)以外,也会将名称与ID咨询转换成P4 Info档案,P4 Info档案将与编译好的P4 binary(bmv2→json,Tofino→bin)一起传送给装置上的Agent,而P4 Info也会将进入给控制器供控制器去查询。
下面是将p4原始码转换成P4 Info的例子,在P4 Info中并不会存在名称,所有的名称都会转换成ID来表示,而不同的ID会指向不同的讯息,像是Table或是Match Field等等。
当控制器拿到P4 Info之后,即可透过P4 Info来产生P4 Runtime的讯息。下面范例展示了一个用于vrf_classifier_table这个Table的Table Entry。
以上内容来源于:https://p4tw.org/p4runtime-p4-info-intro/