在正式介绍P4runtime基础之前,先说一说P4的编译和实现的过程
p4info.txt:该文件包含了各个表和操作,它们的id用一个索引值来表示,比如a表用b操作,不会直接说用名字为B的操作,而是说用索引为xxx的操作,然后锁定到b上执行相关的功能,其次,用了一个bitwith来描述,要访问的数据的比特长度是多长。
p4c编译器将p4编译成两份文件,其中一份是p4info.txt,另一份是bmv2.json(在bmv2这个p4target中是这种格式),将这两个文件再整合起来,作为配置,放到交换机中。另一方面,P4 Info也会将进入给控制器供控制器去查询,当控制器拿到P4 Info之后,即可透过P4 Info来产生P4 Runtime的讯息。
从右边的图可以看出,控制平面和P4Runtime服务器是以p4runtime.proto的rpc支持的,具体可以看下文,介绍了P4和P4runtime的具体工作
P4 与 P4Runtime 介绍 - 知乎 (zhihu.com)
通过make start,我们创建了两个容器,其中一个是mininet另一个是onos,但是在本文中没有被用到。(我这里用的是restart)
用make mn-log可以查看数据平面的基本创建信息
这个拓扑如顶上的那幅图所示,是一个2x2的拓扑,其中h1a h1b h1c被划在一个子网中,其他在别的子网,mininet容器被创建以后,在tmp文件夹的每一个转发设备下生成了三个文件
tmp/leaf1/stratum_bmv2.log
:包含了叶节点的stratum_bmv2日志tmp/leaf1/chassis-config.txt
: Stratum“机箱配置”文件,用于指定交换机启动时使用的初始端口配置;该文件由mininet/topo-v6.py调用的StratumBmv2Switch类自动生成。tmp/leaf1/write-reqs.txt
: 交换机处理的所有P4Runtime写入请求的日志(如果交换机未接收到任何写入请求,则该文件可能不存在)。在本部分中,我们将使用P4Runtime Shell,这是一个交互式Python CLI,可用于连接P4Runtime服务器并运行P4Runtime命令。例如,它可以用于创建、读取、更新和删除流表条目。
shell可以在两种模式下启动,有或没有P4管道配置。在第一种情况下,shell将使用P4Runtime SetPipelineConfig RPC将给定的管道配置推送到交换机;在第二种情况下,shell将尝试检索交换机中当前配置的P4Info。
在这两种情况下,shell都会使用P4Info文件做如下工作:
最后,连接P4runtime服务器,有几个重要项:
util/p4rt-sh --grpc-addr localhost:50001 --config
p4src/build/p4info.txt,p4src/build/bmv2.json --election-id 0,1
--config p4src/build/p4info.txt,p4src/build/bmv2.json:这个配置包含了两个关键文件,一个是bmv2.json文件,另一个是P4info文件:分别描述了交换机的行为模型的具体行为,P4info则指定可通过P4Runtime访问的P4实体的元数据,实体与P4源代码中的实例化对象具有一一对应关系,在运行时安装表条目时需要该文件,额外的,还有一个重要的事情,我们可以看到这两个文件是在build下的,是编译后的,所以我们需要先make p4-build才可以使用rumtime
--election-id 0,1 当连接到P4Runtime服务器时,规范要求我们提供一个主控权选举ID,以便能够写入状态,例如管道配置和表条目,通过这个指令,我们可以访问到数据平面交换机leaf1
好的,现在我们进来了rumtime的命令行,我们可以用各种指令访问到p4交换机它现在身上的表和操作或者计数器有哪些,也可以访问到表、操作、计数器对应的值,让我们来看看吧!如果想知道一个table的具体内容,可以用tables["IngressPipeImpl.
这里有一些功能和表是涉及到后面的代码的,我们先不在乎这些,就看看这几个访问的指令的用法就好了,分别是:tables
, actions
, action_profiles
, counters
, direct_counters
大家还可以看看添加表项或者counter的用法,这里就不多说了:
首先,使用make mn-cli这个命令,打开mininet的命令行
为两个主机设计静态的条目,在这里,主机1a把1b的ipv6地址和以太网地址对上,然后用h1a的以太网0接口这个网卡来交互
h1a ip -6 neigh replace 2001:1:1::B lladdr 00:00:00:00:00:1B dev h1a-eth0
h1b ip -6 neigh replace 2001:1:1::A lladdr 00:00:00:00:00:1A dev h1b-eth0
使用ip neigh show就可以查看邻居了
但是现在呢,你尝试去ping双方并没有用,因为,就算你主机知道在哪,p4交换机不知道
为了让交换机能够转发,我们需要做出如下设置,正好对应了顶上的图
Match (Ethernet dest) | Egress port number |
---|---|
00:00:00:00:00:1B |
4 |
00:00:00:00:00:1A |
3 |
在p4runtime的命令行中,输入:
te = table_entry['IngressPipeImpl.l2_exact_table'](action='IngressPipeImpl.set_egress_port')
te.match['hdr.ethernet.dst_addr'] = '00:00:00:00:00:1A'
te.action['port_num'] = '3'
te.insert()
te = table_entry['IngressPipeImpl.l2_exact_table'](action='IngressPipeImpl.set_egress_port')
te.match['hdr.ethernet.dst_addr'] = '00:00:00:00:00:1B'
te.action['port_num'] = '4'
te.insert()
这样就打了两个表项进去了,注意格式,是:
到此,我们就成功插入了表项了,来看看表项:
好了,我们实现了双方的互ping,实验很简单,主要是对操作以及原理的理解。