美文网首页
ONOS-P4-Tutorial-Ⅱ

ONOS-P4-Tutorial-Ⅱ

作者: SmartSloth | 来源:发表于2020-05-20 14:35 被阅读0次

    练习2:桥接

    说明:本文翻译自onos-p4-tutorialExercise 2: Bridging,用于理解纪录L2转发逻辑

    在本练习中,您将修改P4程序和ONOS应用程序,以增加对以太网(L2)桥接的支持,以支持连接到同一leaf交换机且属于同一子网的主机。

    总览

    ONOS应用程序假定给定子网的主机都连接到相同的leaf,并且两个不同leaf的两个接口无法配置相同的IPv6子网。换句话说,仅对连接到同一leaf的主机允许L2桥接。

    本教程中使用的Mininet脚本topo.py定义了4个子网:

    • 2001:1:1::/64有3台主机(h1ah1b,和h1c)连接到leaf1
    • 2001:1:2::/64有1台主机(h2)连接到leaf1
    • 2001:2:3::/64有1台主机(h3)连接到leaf2
    • 2001:2:4::/64有1台主机(h4)连接到leaf2

    相同的IPv6前缀在netcfg.json文件中定义,用于为ONOS提供接口配置。

    尝试ping主机

    首先,尝试使用Mininet对第一个子网的任意两个主机执行ping操作。它应该不起作用,因为您尚未在P4中实现任何桥接逻辑,也没有为其安装表条目。

    在Mininet CLI上:

    mininet> h1a ping h1b
    PING 2001:1:1::b(2001:1:1::b) 56 data bytes
    From 2001:1:1::a icmp_seq=1 Destination unreachable: Address unreachable
    From 2001:1:1::a icmp_seq=2 Destination unreachable: Address unreachable
    From 2001:1:1::a icmp_seq=3 Destination unreachable: Address unreachable
    ...
    

    但是,由于h1a预期会生成NDP邻居请求(NS)消息以发现h1b的以太网地址,并且由于我们hostprovider在上一个练习中已经激活了该应用程序(请记住将NDP数据包克隆到CPU的ACL流规则),因此我们希望ONOS能够发现主机h1a。要进行检查,请使用ONOS CLI:

    onos> hosts -s
    id=00:00:00:00:00:1A/None, mac=00:00:00:00:00:1A, locations=[device:leaf1/3], vlan=None, ip(s)=[2001:1:1::a]
    

    hostprovider应用已通过嗅探NDP NS数据包获悉了主机MAC地址,位置和IPv6地址。

    练习步骤

    1. 修改P4程序

    main.p4的入口pipeline中,我们已经定义了完成练习所需的一些操作-即set_output_port单播数据包以及set_multicast_group从多个端口发送数据包,例如NDP NS消息。稍后将由ONOS应用创建多播组。缺少的是使用这些操作的表。

    第一步将是创建一个L2表,其中要match目的以太网地址和上述actions。您需要支持两种类型的目标地址:

    1. Broadcast/multicast条目:将复制的NDP邻居请求(NS)消息复制到所有面向主机的端口;

    2. Unicast条目:发现主机后,将由控制平面(即ONOS应用)填充。

    与广播到以太网目标地址FF:FF:FF:FF:FF:FF的ARP消息不同,NDP消息使用IPv6广播/组播数据包,该数据包发送到RFC2464指定的特殊以太网地址。这些目标地址以33:33为前缀,后四个八位位组是IPv6目标多播地址的后四个八位位组。在不深入研究RFC2464细节的情况下,对此类IPv6广播/多播数据包进行匹配的最直接方法是在33:33:**:**:**:**上使用三元匹配,其中*表示“不在乎”。

    头脑风暴:您将为此表使用哪种类型的匹配键(例如exact,LPM和ternary)?exact对多播条目有效吗?使用非精确单播条目是否有弊端?我们的解决方案对每种类型的条目使用两个L2表(对于单播来说是精确的,对于多播来说是ternary),但是您可以选择不同的方法。

    注意:为简单起见,我们不会使用VLAN来划分L2域,但是您可以添加对VLAN的支持,作为额外的功劳练习。

    创建L2表后,您需要在入口pipeline(IngressPipeImpl)的apply块区域中应用这些表。

    完成后,您可以在tutorial目录使用make p4编译程序。在继续操作之前,请确保解决所有编译器错误。

    此时,您的P4管道应已准备好进行测试。

    2. 运行PTF测试

    L2桥接行为的测试位于中ptf/tests/bridging.py。打开该文件,然后在提示的地方进行修改(查找TODO EXERCISE 2)。

    要运行此练习的所有测试:

    cd ptf
    make bridging
    

    此命令将运行bridging组中的所有测试(即的内容 ptf/tests/bridging.py)。要运行特定的测试用例,可以使用:

    make <PYTHON MODULE>.<TEST CASE NAME>
    

    例如:

    make bridging.ArpNdpRequestWithCloneTest
    

    回溯检查

    为确保新更改不会破坏其他功能,请确保也对先前的练习进行测试。

    make packetio
    make bridging
    

    如果所有测试成功,那么恭喜!您可以转到下一步。

    3. 修改ONOS应用

    下一步将是修改ONOS应用程序,以控制之前修改的P4程序的L2桥接部分。

    您将需要修改的源代码位于:app/src/main/java/org/p4/p4d2/tutorial/L2BridgingComponent.java

    根据提示修改代码(查找TODO EXERCISE 2)。

    完整的方法实现以插入L2流规则

    这个应用程序组件定义了两个事件侦听器,它们位于L2BridgingComponent类的底部,InternalDeviceListener用于设备事件(例如,连接新交换机)和InternalHostListener主机事件(例如,发现新主机)。这些监听器依次调用以下方法:

    • setUpDevice():负责为所有面向主机的端口创建一个多播组,并为广播/多播数据包(例如ARP和NDP消息)插入流规则;

    • learnHost():负责根据发现的主机位置为交换机插入单播L2条目。

    为了支持重新加载应用程序实现,在激活时,ONOS已知的所有设备和主机在组件激活时也会调用这些方法(查找方法activate()setUpAllDevices())。

    为简单起见,我们的广播域将被限制在单个设备上,即,我们仅允许对同一leaf交换机的端口进行数据包复制的广播。因此,我们可以将去往多播组中spine的端口排除在外。为了确定端口是否应该面向主机,我们查看netcfg.json文件中的接口配置(查找JSON文件的ports部分)。

    入门代码已经提供了insertMulticastGroup()方法的实现;您需要完成其他两种方法的实现:insertMulticastFlowRules()learnHost()

    启用桥接组件

    一旦确定您上一步的解决方案可以工作,那么在构建和重新加载应用程序之前,请记得通过在类定义顶部将enabled标志设置为true来启用组件:

    /**
     * App component that configures devices to provide L2 bridging capabilities.
     */
    @Component(
            immediate = true,
            enabled = true
    )
    public class L2BridgingComponent {
        ...
    

    生成并重新加载应用

    在ONOS运行时,使用以下命令来构建和重新加载您的应用程序:

    $ make app-build app-reload
    

    在构建应用程序时,修改后的P4编译器的输出(bmv2.jsonp4info.txt)将与Java类一起打包在一起。重新加载应用程序后,您应该看到如下消息,表明已设置了新的pipeline配置并已将L2BridgingComponent激活:

    INFO  [PiPipeconfManager] Unregistered pipeconf: org.p4.srv6-tutorial (fingerprint=2e:39:f0:81:cd:a3:76:20)
    INFO  [PipeconfLoader] Found 1 outdated drivers for pipeconf 'org.p4.srv6-tutorial', removing...
    INFO  [PiPipeconfManager] New pipeconf registered: org.p4.srv6-tutorial (fingerprint=2e:39:f0:81:1f:37:e6:82)
    INFO  [PipelineConfigClientImpl] Setting pipeline config for device:leaf1 to org.p4.srv6-tutorial...
    ...
    INFO  [MainComponent] Waiting to remove flows and groups from previous execution of org.p4.srv6-tutorial..
    ...
    INFO  [MainComponent] Started
    INFO  [L2BridgingComponent] Started
    ...
    INFO  [L2BridgingComponent] *** L2 BRIDGING - Starting initial set up for device:leaf1...
    INFO  [L2BridgingComponent] Adding L2 multicast group with 4 ports on device:leaf1...
    INFO  [L2BridgingComponent] Adding L2 multicast rules on device:leaf1...
    INFO  [L2BridgingComponent] Adding L2 unicast rule on device:leaf1 for host 00:00:00:00:00:1A/None (port 3)...
    ...
    

    了解ONOS错误日志

    在Mininet中尝试解决方案之前,值得查看一下ONOS日志中可能的错误。重新加载应用程序时可能会看到两种主要类型的错误:

    1. 写入错误,例如删除不存在的实体或插入已经存在的实体:

      WARN  [WriteResponseImpl] Unable to DELETE PRE entry on device...: NOT_FOUND Multicast group does not exist ...
      WARN  [WriteResponseImpl] Unable to INSERT table entry on device...: ALREADY_EXIST Match entry exists, use MODIFY if you wish to change action ...
      

      这些通常是暂时性错误,您不必担心它们。它们描述了ONOS内部设备状态的暂时不一致,应通过定期对帐(reconciliation)机制尽快恢复这种状态。 ONOS核心会定期轮询设备状态,以确保其内部表示准确无误,同时将任何pending的修改写入设备,以解决这些错误。

      否则,如果您看到它们定期出现(每3-4秒一次),则表示对帐过程不起作用,并且其他地方出了问题。尝试重新加载应用(make app-reload);如果仍不能解决警告,请与教员联系。

    2. Translation错误,表示ONOS无法将应用程序生成的流规则(或组)转换为与P4Info兼容的表示形式。例如:

      WARN  [P4RuntimeFlowRuleProgrammable] Unable to translate flow rule for pipeconf 'org.p4.srv6-tutorial':...
      

      仔细阅读错误消息,并根据需要对应用程序进行更改。可能您使用的表、匹配字段或操作名称在P4Info中不存在。检查您的P4Info文件,修改并重新加载应用程序(make app-build app-reload)。

    4. 在Mininet上测试L2桥接

    现在,该应用程序已被修改并重新加载,并且ONOS日志中没有潜在的有害错误,您应该能够重复在练习开始时执行的相同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=2 ttl=64 time=0.580 ms
    64 bytes from 2001:1:1::b: icmp_seq=3 ttl=64 time=0.483 ms
    64 bytes from 2001:1:1::b: icmp_seq=4 ttl=64 time=0.484 ms
    ...
    

    检查ONOS日志,您应该看到与发现主机有关的消息,该主机h1b现在正在从中接收NDP NS消息h1a并以NDP NA消息进行回复(请记住h1a在练习开始时已经发现):

    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)...
    

    故障排除

    如果ping不起作用,您可以采取以下步骤来排除网络故障:

    1. 检查所有流规则和组是否已成功写入设备。使用ONOS CLI命令(例如flows -s any device:leaf1和)groups any device:leaf1,验证所有流和组都处于状态ADDED。如果您看到其他状态,例如PENDING_ADD,则将这些条目写入设备,请检查ONOS日志中是否存在错误。您还可以使用ONOS网络用户界面检查流程和群组状态。

    2. 使用表计数器来验证是否按预期命中了表。如果您尚未为L2表定义直接计数器,请修改P4程序以添加一些计数器,然后构建并重新加载应用程序(make app-build app-reload)。ONOS应该每3-4秒(对帐过程的同一时间段)自动检测一次并轮询计数器。要检查其值,可以使用ONOS CLI(flows -s any device:leaf1)或Web UI。

    3. 仔细检查PTF测试,并确保您在中创建了类似的流规则L2BridgingComponent.java。你注意到有什么区别吗?

    4. 查看BMv2日志中可能的错误。检查文件/tmp/bmv2-<SW-NAME>-log或使用bm-log <SW-NAME>bash命令。

    5. 如果在这里仍然无法正常工作,请与一位教员联系以寻求帮助。

    5. 可视化ONOS Web UI上的主机

    从教程VM(例如Firefox)中打开浏览器,前往http://127.0.0.1:8181/onos/ui。访问时,请使用用户名onos和密码rocks

    要在拓扑视图上切换显示/不显示主机,请按H键。

    恭喜啦

    您已经完成练习2!现在,您的交换矩阵能够在同一子网中的主机之间转发数据包,并连接到同一leaf交换机。

    相关文章

      网友评论

          本文标题:ONOS-P4-Tutorial-Ⅱ

          本文链接:https://www.haomeiwen.com/subject/aragohtx.html