Ngsdn-Tutorial-Ⅲ

练习3-使用ONOS作为控制平面

说明:本教程翻译自Next-Gen SDN TutorialExercise 3 - Using ONOS as the control plane,自用学习Docker-P4-ONOS

本练习提供了对ONOS的动手介绍,您将在其中学习如何:

  1. 启动ONOS以及一组用于基础服务(例如拓扑发现)的内置应用程序
  2. 加载自定义的ONOS应用和pipeconf
  3. stratum_bmv2使用P4Runtime和gNMI将配置文件推送到ONOS以发现和控制交换机
  4. 通过使用P4Runtime数据包入/出验证ONOS是否能够自动发现所有链接

为此,将要求您对pipeconf的Java文件实现进行简单的更改,以使ONOS的内置应用程序可以通过数据包输入/输出执行拓扑发现。

带有P4Runtime的控制器数据包I/O

p4src/main.p4下的P4程序支持在P4RuntimePacketInPacketOut消息中携带任意元数据。定义了两个特殊的标头,并使用标准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_metadataP4Info文件的一部分,以确定在帧开始处要剥离的位数,并填充PacketIn消息的相应metdata字段,包括在这种情况下的入口。

类似地,当Stratum接收到P4Runtime的PacketOut消息时,它将使用PacketOut的元数据字段中的值来序列化并在帧之前添加一个packet_out_header_t,然后再将其馈送到管道解析器。

练习步骤

1.修改ONOS管道解释器

P4入门代码已经提供了对数据包输入/输出的支持,包括ACL表操作,用于将数据包克隆到CPU端口(用于生成数据包输入)。

PipelineInterpreter是ONOS驱动程序的行为,该行为用于将包输入/输出的ONOS表示映射到与给定P4程序一致的包。

具体来说,要使用基于LLDP的链接发现之类的服务,ONOS内置应用程序需要能够设置数据包输出的输出端口并访问数据包输入的原始入口端口。

接下来,将要求您对PipelineInterpreter进行一些简单的更改:

  1. 打开文件:app/src/main/java/org/onosproject/ngsdn/tutorial/pipeconf/InterpreterImpl.java

  2. 根据需要修改(查找TODO EXERCISE 3),详情如下:

    • 查找一个名为的方法buildPacketOut,修改实现以使用与P4Info文件中指定的标头相同的egress port元数据字段名称packet_out
    • 查找mapInboundPacket方法,修改实现以使用与P4Info文件中指定的标头相同的ingress port元数据字段名称packet_in
  3. 使用以下命令构建ONOS应用程序(包括pipeconf):

    make app-build
    

如果需要,最后一条命令将触发P4程序的构建。P4编译器的输出(bmv2.jsonp4info.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}

这些规则是hostproviderlldpprovider应用为每个设备自动生成的流程目标转换的结果。

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_TYPEICMPV6_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的ActionProfileGroupActionProfileMember。这个特定的组由应用程序创建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视图。

device-leaf1-details-panel.png

在顶部面板中,给出了该设备的常规Pipeconf数据。在下面的面板中,列出了P4程序中找到的相同表,并定期更新匹配的表条目和数据包的数量。

onos-gui-pipeconf-leaf1.png

单击表行将弹出详细信息面板,显示匹配字段、操作、操作参数位宽等的详细信息。

恭喜你!

您已经完成了第三次练习!如果在此课程结束之前还有时间,您可以检查以下奖励步骤。

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的PacketInPacketOut;
  • P4Runtime读取RPC,用于定期转储表条目和读取计数器;
  • gNMI获取RPC以读取端口计数器。

完成后,请记住禁用ONOS中的gRPC消息日志记录,以避免影响性能:

onos> cfg set org.onosproject.grpc.ctl.GrpcChannelControllerImpl enableMessageLog false
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342