练习3-使用ONOS作为控制平面
说明:本教程翻译自Next-Gen SDN Tutorial的Exercise 3 - Using ONOS as the control plane,自用学习Docker-P4-ONOS
本练习提供了对ONOS的动手介绍,您将在其中学习如何:
- 启动ONOS以及一组用于基础服务(例如拓扑发现)的内置应用程序
- 加载自定义的ONOS应用和pipeconf
-
stratum_bmv2
使用P4Runtime和gNMI将配置文件推送到ONOS以发现和控制交换机 - 通过使用P4Runtime数据包入/出验证ONOS是否能够自动发现所有链接
为此,将要求您对pipeconf的Java文件实现进行简单的更改,以使ONOS的内置应用程序可以通过数据包输入/输出执行拓扑发现。
带有P4Runtime的控制器数据包I/O
p4src/main.p4下的P4程序支持在P4RuntimePacketIn
和PacketOut
消息中携带任意元数据。定义了两个特殊的标头,并使用标准P4注释进行了注释@controller_header
:
@controller_header("packet_in")
header packet_in_header_t {
port_num_t ingress_port;
bit<7> _pad;
}
@controller_header("packet_out")
header packet_out_header_t {
port_num_t egress_port;
bit<7> _pad;
}
这些标头用于携带输入包的原始交换机入口端口,并指定输出包的预期输出端口。
当Stratum中的P4Runtime代理从交换器CPU端口接收到一个数据包时,它希望packet_in_header_t
是帧中的第一个报头。实际上,它会查看controller_packet_metadata
P4Info文件的一部分,以确定在帧开始处要剥离的位数,并填充PacketIn
消息的相应metdata字段,包括在这种情况下的入口。
类似地,当Stratum接收到P4Runtime的PacketOut
消息时,它将使用PacketOut
的元数据字段中的值来序列化并在帧之前添加一个packet_out_header_t
,然后再将其馈送到管道解析器。
练习步骤
1.修改ONOS管道解释器
P4入门代码已经提供了对数据包输入/输出的支持,包括ACL表操作,用于将数据包克隆到CPU端口(用于生成数据包输入)。
PipelineInterpreter
是ONOS驱动程序的行为,该行为用于将包输入/输出的ONOS表示映射到与给定P4程序一致的包。
具体来说,要使用基于LLDP的链接发现之类的服务,ONOS内置应用程序需要能够设置数据包输出的输出端口并访问数据包输入的原始入口端口。
接下来,将要求您对PipelineInterpreter
进行一些简单的更改:
打开文件:
app/src/main/java/org/onosproject/ngsdn/tutorial/pipeconf/InterpreterImpl.java
-
根据需要修改(查找
TODO EXERCISE 3
),详情如下:- 查找一个名为的方法
buildPacketOut
,修改实现以使用与P4Info文件中指定的标头相同的egress port元数据字段名称packet_out
。 - 查找
mapInboundPacket
方法,修改实现以使用与P4Info文件中指定的标头相同的ingress port元数据字段名称packet_in
。
- 查找一个名为的方法
-
使用以下命令构建ONOS应用程序(包括pipeconf):
make app-build
如果需要,最后一条命令将触发P4程序的构建。P4编译器的输出(bmv2.json
和p4info.txt
)被复制到应用程序资源文件夹(app/src/main/resources
)中,并将包含在ONOS应用程序二进制文件中。启动P4Runtime连接后,ONOS应用程序中包含的副本将是ONOS部署到交换机的副本。
2.启动ONOS
在终端窗口中,键入:
$ make reset start
如果它们是从先前的练习中运行的,此命令将重新启动ONOS和Mininet容器,并清除任何先前的状态。
启动ONOS容器的参数中指定docker-compose.yml。容器配置为传递环境变量ONOS_APPS
,该环境变量用于定义要在启动期间加载的内置应用程序。
在我们的例子中,此变量具有值:
ONOS_APPS=gui2,drivers.bmv2,lldpprovider,hostprovider
请求ONOS预加载以下内置应用程序:
-
gui2
:ONOS Web用户界面(位于http://localhost:8181/onos/ui) -
drivers.bmv2
:基于P4Runtime,gNMI和gNOI的BMv2/Stratum驱动程序 -
lldpprovider
:基于LLDP的链路发现应用程序 -
hostprovider
:主机发现应用程序
ONOS启动后,您可以使用以下make onos-log
命令检查其日志。
要验证是否已激活所有必需的应用程序,请在新的终端窗口中运行以下命令以访问ONOS CLI。rocks
出现提示时使用密码:
$ make onos-cli
如果看到以下错误,则表明ONOS仍在启动;请稍候,然后重试。
ssh_exchange_identification: Connection closed by remote host
make: *** [onos-cli] Error 255
当看到密码提示时,键入默认密码:rocks
在ONOS CLI中键入以下命令以显示正在运行的应用程序的列表:
onos> apps -a -s
确保您看到以下显示的应用程序列表:
* 5 org.onosproject.protocols.grpc 2.2.2 gRPC Protocol Subsystem
* 6 org.onosproject.protocols.gnmi 2.2.2 gNMI Protocol Subsystem
* 29 org.onosproject.drivers 2.2.2 Default Drivers
* 34 org.onosproject.generaldeviceprovider 2.2.2 General Device Provider
* 35 org.onosproject.protocols.p4runtime 2.2.2 P4Runtime Protocol Subsystem
* 36 org.onosproject.p4runtime 2.2.2 P4Runtime Provider
* 37 org.onosproject.drivers.p4runtime 2.2.2 P4Runtime Drivers
* 42 org.onosproject.protocols.gnoi 2.2.2 gNOI Protocol Subsystem
* 52 org.onosproject.hostprovider 2.2.2 Host Location Provider
* 53 org.onosproject.lldpprovider 2.2.2 LLDP Link Provider
* 66 org.onosproject.drivers.gnoi 2.2.2 gNOI Drivers
* 70 org.onosproject.drivers.gnmi 2.2.2 gNMI Drivers
* 71 org.onosproject.pipelines.basic 2.2.2 Basic Pipelines
* 72 org.onosproject.drivers.stratum 2.2.2 Stratum Drivers
* 161 org.onosproject.gui2 2.2.2 ONOS GUI2
* 181 org.onosproject.drivers.bmv2 2.2.2 BMv2 Drivers
这绝对是比中定义的应用更多的应用$ONOS_APPS
。这是因为ONOS中的每个应用程序都可以将其他应用程序定义为依赖项。加载应用程序时,ONOS会自动解决依赖关系并加载所有其他必需的应用程序。
要退出ONOS CLI,请使用Ctrl-D
。这只会结束CLI进程,而不会停止ONOS进程。
发生错误时重新启动ONOS
如果出现任何问题并且需要杀死ONOS,则可以使用命令make reset start
重新启动Mininet和ONOS。
3.加载应用程序并注册pipeconf
在第二个终端窗口中,键入:
$ make app-reload
此命令将上传到ONOS并激活先前构建的应用程序二进制文件(位于app/target/ngsdn-tutorial-1.0-SNAPSHOT.oar
)。
激活应用程序后,您应该在ONOS日志(make onos-log
)中看到以下消息,表明pipeconf已注册并且不同的应用程序组件已启动:
INFO [PiPipeconfManager] New pipeconf registered: org.onosproject.ngsdn-tutorial (fingerprint=...)
INFO [MainComponent] Started
或者,您可以使用ONOS CLI(make onos-cli
)命令显示已注册pipeconf的列表:
onos> pipeconfs
4.将netcfg推送到ONOS
现在,ONOS和Mininet正在运行,现在该让ONOS知道如何到达这四个交换机并对其进行控制了。我们通过使用位于mininet/netcfg.json的配置文件来执行此操作,该配置文件包含以下信息:
- 与每个Stratum设备关联的gRPC地址和端口;
- 在
stratum-bmv2
这种情况下,用于每个设备的ONOS驱动程序; - 在
org.onosproject.ngsdn-tutorial
这种情况下,如PipeconfLoader.java中所定义,用于每个设备的pipeconf; - 特定于我们的自定义应用程序的配置,例如
myStationMac
或标志,用于指示是否必须将交换机视为spine。
该文件还包含与每个交换机接口关联的IPv6配置有关的信息。在下一个练习中,我们将详细讨论此信息。
在终端窗口上,键入:
$ make netcfg
此命令会将推netcfg.json
送到ONOS,触发发现和配置4台交换机。
检查ONOS日志(make onos-log
),您应该看到类似以下的消息:
INFO [GrpcChannelControllerImpl] Creating new gRPC channel grpc:///mininet:50001?device_id=1...
...
INFO [StreamClientImpl] Setting mastership on device:leaf1...
...
INFO [PipelineConfigClientImpl] Setting pipeline config for device:leaf1 to org.onosproject.ngsdn-tutorial...
...
INFO [GnmiDeviceStateSubscriber] Started gNMI subscription for 6 ports on device:leaf1
...
INFO [DeviceManager] Device device:leaf1 port [leaf1-eth1](1) status changed (enabled=true)
INFO [DeviceManager] Device device:leaf1 port [leaf1-eth2](2) status changed (enabled=true)
INFO [DeviceManager] Device device:leaf1 port [leaf1-eth3](3) status changed (enabled=true)
INFO [DeviceManager] Device device:leaf1 port [leaf1-eth4](4) status changed (enabled=true)
INFO [DeviceManager] Device device:leaf1 port [leaf1-eth5](5) status changed (enabled=true)
INFO [DeviceManager] Device device:leaf1 port [leaf1-eth6](6) status changed (enabled=true)
5.使用ONOS CLI验证网络配置
使用访问ONOS CLI make onos-cli
。输入以下命令以验证之前推送的网络配置:
onos> netcfg
设备
验证是否已找到并连接了所有4个设备:
onos> devices -s
id=device:leaf1, available=true, role=MASTER, type=SWITCH, driver=stratum-bmv2:org.onosproject.ngsdn-tutorial
id=device:leaf2, available=true, role=MASTER, type=SWITCH, driver=stratum-bmv2:org.onosproject.ngsdn-tutorial
id=device:spine1, available=true, role=MASTER, type=SWITCH, driver=stratum-bmv2:org.onosproject.ngsdn-tutorial
id=device:spine2, available=true, role=MASTER, type=SWITCH, driver=stratum-bmv2:org.onosproject.ngsdn-tutorial
确保查看available=true
所有设备。这意味着ONOS已连接到设备,并且管道配置已推送。
端口
检查端口信息,该信息由ONOS通过执行针对OpenConfig接口模型的gNMI Get RPC获得:
onos> ports -s device:spine1
id=device:spine1, available=true, role=MASTER, type=SWITCH, driver=stratum-bmv2:org.onosproject.ngsdn-tutorial
port=[spine1-eth1](1), state=enabled, type=copper, speed=10000 , ...
port=[spine1-eth2](2), state=enabled, type=copper, speed=10000 , ...
检查端口统计信息,也可以通过gNMI查询OpenConfig接口模型获得:
onos> portstats device:spine1
deviceId=device:spine1
port=[spine1-eth1](1), pktRx=114, pktTx=114, bytesRx=14022, bytesTx=14136, pktRxDrp=0, pktTxDrp=0, Dur=173
port=[spine1-eth2](2), pktRx=114, pktTx=114, bytesRx=14022, bytesTx=14136, pktRxDrp=0, pktTxDrp=0, Dur=173
链接
验证是否已找到所有链接。您应该总共看到8个链接:
onos> links
src=device:leaf1/1, dst=device:spine1/1, type=DIRECT, state=ACTIVE, expected=false
src=device:leaf1/2, dst=device:spine2/1, type=DIRECT, state=ACTIVE, expected=false
src=device:leaf2/1, dst=device:spine1/2, type=DIRECT, state=ACTIVE, expected=false
src=device:leaf2/2, dst=device:spine2/2, type=DIRECT, state=ACTIVE, expected=false
src=device:spine1/1, dst=device:leaf1/1, type=DIRECT, state=ACTIVE, expected=false
src=device:spine1/2, dst=device:leaf2/1, type=DIRECT, state=ACTIVE, expected=false
src=device:spine2/1, dst=device:leaf1/2, type=DIRECT, state=ACTIVE, expected=false
src=device:spine2/2, dst=device:leaf2/2, type=DIRECT, state=ACTIVE, expected=false
如果看不到任何链接,请检查ONOS日志中是否有进出包处理错误。如果出现错误,则可能是您未正确修改InterpreterImpl.java
。在这种情况下,请杀死ONOS容器(make reset
)并返回执行步骤1。
注意:从理论上讲,没有必要杀死并重新启动ONOS。但是,虽然ONOS支持使用修改后的应用程序重新加载应用程序,但本教程中使用的ONOS版本(2.2.2是撰写本文时的最新长期支持版本)不支持重新加载pipeconf behavior classes,因为旧的类仍将使用。因此,要重新加载InterpreterImpl.java
的修改版本,您需要先杀死ONOS。
流规则和组
检查ONOS流规则,每个设备应看到12条流规则。例如,显示设备上到目前为止安装的所有流规则leaf1
:
onos> flows -s any device:leaf1
deviceId=device:leaf1, flowRuleCount=12
ADDED, bytes=0, packets=0, table=IngressPipeImpl.acl_table, priority=40000, selector=[ETH_TYPE:arp], treatment=[immediate=[IngressPipeImpl.clone_to_cpu()]]
ADDED, bytes=3596, packets=29, table=IngressPipeImpl.acl_table, priority=40000, selector=[ETH_TYPE:lldp], treatment=[immediate=[IngressPipeImpl.clone_to_cpu()]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.acl_table, priority=40000, selector=[ETH_TYPE:ipv6, IP_PROTO:58, ICMPV6_TYPE:136], treatment=[immediate=[IngressPipeImpl.clone_to_cpu()]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.acl_table, priority=40000, selector=[ETH_TYPE:ipv6, IP_PROTO:58, ICMPV6_TYPE:135], treatment=[immediate=[IngressPipeImpl.clone_to_cpu()]]
ADDED, bytes=3596, packets=29, table=IngressPipeImpl.acl_table, priority=40000, selector=[ETH_TYPE:bddp], treatment=[immediate=[IngressPipeImpl.clone_to_cpu()]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.l2_exact_table, priority=10, selector=[hdr.ethernet.dst_addr=0xbb00000001], treatment=[immediate=[IngressPipeImpl.set_egress_port(port_num=0x1)]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.l2_exact_table, priority=10, selector=[hdr.ethernet.dst_addr=0xbb00000002], treatment=[immediate=[IngressPipeImpl.set_egress_port(port_num=0x2)]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.l2_ternary_table, priority=10, selector=[hdr.ethernet.dst_addr=0x333300000000&&&0xffff00000000], treatment=[immediate=[IngressPipeImpl.set_multicast_group(gid=0xff)]]
ADDED, bytes=3596, packets=29, table=IngressPipeImpl.l2_ternary_table, priority=10, selector=[hdr.ethernet.dst_addr=0xffffffffffff&&&0xffffffffffff], treatment=[immediate=[IngressPipeImpl.set_multicast_group(gid=0xff)]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.my_station_table, priority=10, selector=[hdr.ethernet.dst_addr=0xaa00000001], treatment=[immediate=[NoAction()]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.routing_v6_table, priority=10, selector=[hdr.ipv6.dst_addr=0x20010002000400000000000000000000/64], treatment=[immediate=[GROUP:0xec3b0000]]
ADDED, bytes=0, packets=0, table=IngressPipeImpl.routing_v6_table, priority=10, selector=[hdr.ipv6.dst_addr=0x20010002000300000000000000000000/64], treatment=[immediate=[GROUP:0xec3b0000]]
该列表包括由ONOS内置应用程序以及我们的自定义应用程序安装的流规则。要检查哪些流规则来自内置应用程序,您可以使用应用程序ID如appId=org.onosproject.core
用命令grep
输出flows
:
onos> flows any device:leaf1 | grep appId=org.onosproject.core
id=100001e5fba59, state=ADDED, bytes=0, packets=0, duration=355, liveType=UNKNOWN, priority=40000, tableId=IngressPipeImpl.acl_table, appId=org.onosproject.core, selector=[ETH_TYPE:arp], treatment=DefaultTrafficTreatment{immediate=[IngressPipeImpl.clone_to_cpu()], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
id=10000217b5edd, state=ADDED, bytes=28644, packets=231, duration=355, liveType=UNKNOWN, priority=40000, tableId=IngressPipeImpl.acl_table, appId=org.onosproject.core, selector=[ETH_TYPE:lldp], treatment=DefaultTrafficTreatment{immediate=[IngressPipeImpl.clone_to_cpu()], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
id=1000039959d4d, state=ADDED, bytes=0, packets=0, duration=355, liveType=UNKNOWN, priority=40000, tableId=IngressPipeImpl.acl_table, appId=org.onosproject.core, selector=[ETH_TYPE:ipv6, IP_PROTO:58, ICMPV6_TYPE:136], treatment=DefaultTrafficTreatment{immediate=[IngressPipeImpl.clone_to_cpu()], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
id=1000078c06d68, state=ADDED, bytes=0, packets=0, duration=355, liveType=UNKNOWN, priority=40000, tableId=IngressPipeImpl.acl_table, appId=org.onosproject.core, selector=[ETH_TYPE:ipv6, IP_PROTO:58, ICMPV6_TYPE:135], treatment=DefaultTrafficTreatment{immediate=[IngressPipeImpl.clone_to_cpu()], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
id=10000d1887c0b, state=ADDED, bytes=0, packets=0, duration=356, liveType=UNKNOWN, priority=40000, tableId=IngressPipeImpl.acl_table, appId=org.onosproject.core, selector=[ETH_TYPE:bddp], treatment=DefaultTrafficTreatment{immediate=[IngressPipeImpl.clone_to_cpu()], deferred=[], transition=None, meter=[], cleared=false, StatTrigger=null, metadata=null}
这些规则是hostprovider
和lldpprovider
应用为每个设备自动生成的流程目标转换的结果。
该hostprovider
应用程序通过嗅探克隆到控制器()的ARP(selector=[ETH_TYPE:arp]
)和NDP数据包(selector=[ETH_TYPE:ipv6, IP_PROTO:58, ICMPV6_TYPE:...]
)来提供主机发现功能treatment=[immediate=[IngressPipeImpl.clone_to_cpu()]]
。类似地,lldpprovider
产生流动目标,嗅探LLDP和BBDP分组(selector=[ETH_TYPE:lldp]
和selector=[ETH_TYPE:bbdp]
)上的所有设备端口作为P4Runtime包奏周期性发射的,允许自动链路发现。
流目标由pipeconf转换为流规则和组,pipeconf提供了Pipeliner
行为实现(PipelinerImpl.java)。此外,这些流规则通过使用ONOS标准的/已知的报头字段(或“标准”的使用ONOS术语),如指定匹配键ETH_TYPE
,ICMPV6_TYPE
等等。这些类型由之前修改的同一管线解释映射到特定P4Info匹配字段InterpreterImpl.java(查找方法mapCriterionType
)
要显示到目前为止已安装的所有组,可以使用以下groups
命令。例如显示组leaf1
:
onos> groups any device:leaf1
deviceId=device:leaf1, groupCount=3
id=0xec3b0000, state=ADDED, type=SELECT, bytes=0, packets=0, appId=org.onosproject.ngsdn-tutorial, referenceCount=0
id=0xec3b0000, bucket=1, bytes=0, packets=0, weight=1, actions=[IngressPipeImpl.set_next_hop(dmac=0xbb00000002)]
id=0xec3b0000, bucket=2, bytes=0, packets=0, weight=1, actions=[IngressPipeImpl.set_next_hop(dmac=0xbb00000001)]
id=0x63, state=ADDED, type=CLONE, bytes=0, packets=0, appId=org.onosproject.core, referenceCount=0
id=0x63, bucket=1, bytes=0, packets=0, weight=-1, actions=[OUTPUT:CONTROLLER]
id=0xff, state=ADDED, type=ALL, bytes=0, packets=0, appId=org.onosproject.ngsdn-tutorial, referenceCount=0
id=0xff, bucket=1, bytes=0, packets=0, weight=-1, actions=[OUTPUT:3]
id=0xff, bucket=2, bytes=0, packets=0, weight=-1, actions=[OUTPUT:4]
id=0xff, bucket=3, bytes=0, packets=0, weight=-1, actions=[OUTPUT:5]
id=0xff, bucket=4, bytes=0, packets=0, weight=-1, actions=[OUTPUT:6]
“Group”是ONOS北向抽象,在内部映射到不同类型的P4Runtime实体。在这种情况下,您应该看到3组,每组3种不同的类型。
SELECT
:映射到P4Runtime的ActionProfileGroup
和ActionProfileMember
。这个特定的组由应用程序创建Ipv6RoutingComponent.java
并安装在P4中routing_v6_table
,以向spine提供ECMP哈希。CLONE
:映射到P4Runtime的CloneSessionEntry
,此处用于将数据包通过数据包输入克隆到控制器。请注意,与P4程序中id=0x63
的相同#define CPU_CLONE_SESSION_ID 99
。该ID硬编码在pipeconf代码中,因为通过InterpreterImpl.java
响应映射到ACL表的流目标并请求克隆数据包(例如NDP和LLDP)来创建该组。ALL
:映射到P4Runtime的MulticastGroupEntry
。在这种情况下,用于将NDP NS数据包广播到所有面向主机的端口。该组由安装L2BridgingComponent.java
,并由P4中的条目使用l2_ternary_table
(使用查找流规则treatment=[immediate=[IngressPipeImpl.set_multicast_group(gid=0xff)]
)
6.测试主机之间的ping
现在已经加载了应用程序,您应该可以重复练习1中执行的相同ping测试:
mininet> h1a ping h1b
PING 2001:1:1::b(2001:1:1::b) 56 data bytes
64 bytes from 2001:1:1::b: icmp_seq=1 ttl=64 time=1068 ms
64 bytes from 2001:1:1::b: icmp_seq=2 ttl=64 time=5.38 ms
64 bytes from 2001:1:1::b: icmp_seq=3 ttl=64 time=1.75 ms
...
与练习1不同,这里我们没有设置任何NDP静态条目。相反,由于上述ALL
分组和l2_ternary_table
流规则,NDP NS和NA数据包由数据平面处理。此外,给定将NDP数据包克隆到控制器的ACL流规则,ONOS可以发现主机。主机发现事件用于L2BridgingComponent.java
在P4中给l2_exact_table
插入条目,以启用同一子网中主机之间的转发。
检查ONOS日志(make onos-log
)。您应该看到与发现主机h1a
和有关的消息h1b
:
INFO [L2BridgingComponent] HOST_ADDED event! host=00:00:00:00:00:1A/None, deviceId=device:leaf1, port=3
INFO [L2BridgingComponent] Adding L2 unicast rule on device:leaf1 for host 00:00:00:00:00:1A/None (port 3)...
...
INFO [L2BridgingComponent] HOST_ADDED event! host=00:00:00:00:00:1B/None, deviceId=device:leaf1, port=4
INFO [L2BridgingComponent] Adding L2 unicast rule on device:leaf1 for host 00:00:00:00:00:1B/None (port 4)...
7.在ONOS Web UI上可视化拓扑
从教程VM(例如Firefox)中打开浏览器,前往http://127.0.0.1:8181/onos/ui。询问时,请使用用户名onos
和密码rocks
。
在这里,您可以随时与之互动并发现ONOS UI。有关如何使用ONOS网络用户界面的更多信息,请参阅以下指南:
https://wiki.onosproject.org/x/OYMg
在显示ONOS拓扑视图的同一页面上:
- 按
H
键盘上的显示主机; - 按下
L
以显示设备标签; - 多次按
A
,直到看到链接统计信息,以包/秒(pps)或位/秒为单位。
在mininet上,只有此时成功ping通的主机才可见。
ONOS通过定期获取每个设备的端口计数器来获取链路统计信息。ONOS在内部使用gNMI读取端口信息,包括计数器。
可以通过Web UI中的各种视图显示所有设备,端口(包括统计信息)、链接、主机、流和组。
7a. 在Web UI中查看Pipeconf数据
在ONOS拓扑视图中,单击Stratum开关之一(例如device:leaf1
),然后出现“设备详细信息”面板。在该面板中,单击Pipeconf图标(最后一个),以打开该设备的Pipeconf视图。
在顶部面板中,给出了该设备的常规Pipeconf数据。在下面的面板中,列出了P4程序中找到的相同表,并定期更新匹配的表条目和数据包的数量。
单击表行将弹出详细信息面板,显示匹配字段、操作、操作参数位宽等的详细信息。
恭喜你!
您已经完成了第三次练习!如果在此课程结束之前还有时间,您可以检查以下奖励步骤。
Bonus:检查stratum_bmv2内部状态
您可以使用P4Runtime Shell转储ONOS当前在交换机上安装的所有表条目。在单独的终端窗口类型上,为leaf1启动一个P4Runtime shell:
$ util/p4rt-sh --grpc-addr localhost:50001 --election-id 0,1
在shell提示符下,键入以下命令以转储ACL表中的所有条目:
P4Runtime sh >>> for te in table_entry["IngressPipeImpl.acl_table"].read():
...: print(te)
...:
您应该看到恰好5个条目,每个条目对应于ONOS中的流规则。例如,在NDP NS数据包上匹配的流规则在P4runtime shell中应如下所示:
table_id: 33557865 ("IngressPipeImpl.acl_table")
match {
field_id: 4 ("hdr.ethernet.ether_type")
ternary {
value: "\\x86\\xdd"
mask: "\\xff\\xff"
}
}
match {
field_id: 5 ("hdr.ipv6.next_hdr")
ternary {
value: "\\x3a"
mask: "\\xff"
}
}
match {
field_id: 6 ("hdr.icmpv6.type")
ternary {
value: "\\x87"
mask: "\\xff"
}
}
action {
action {
action_id: 16782152 ("IngressPipeImpl.clone_to_cpu")
}
}
priority: 40001
Bonus:显示ONOS gRPC日志
ONOS提供了调试功能,该功能允许将与设备交换的所有gRPC消息转储到文件中。要启用此功能,请在ONOS CLI(make onos-cli
)中键入以下命令:
onos> cfg set org.onosproject.grpc.ctl.GrpcChannelControllerImpl enableMessageLog true
检查根目录tmp/onos
中的内容ngsdn-tutorial
。您应该看到许多文件,其中一些以name开头grpc_mininet_
。您应该总共看到4个这样的文件,每个设备一个文件,以用于建立gRPC通道的gRPC端口命名。
检查这些文件之一的内容,您应该看到Protobuf Text格式的gRPC消息转储,例如:
- P4Runtime的
PacketIn
和PacketOut
; - P4Runtime读取RPC,用于定期转储表条目和读取计数器;
- gNMI获取RPC以读取端口计数器。
完成后,请记住禁用ONOS中的gRPC消息日志记录,以避免影响性能:
onos> cfg set org.onosproject.grpc.ctl.GrpcChannelControllerImpl enableMessageLog false