• P4学习——Basic Tunneling



    一、介绍

    在这次实验中,要对上一个实验中完成的IP路由器添加对基本隧道协议的支持。交换机根据目的IP地址进行转发,我们的任务是定义一个新的报头类型来封装IP数据包并修改交换机代码,以便它使用一个新的隧道报头来决定目的端口从而指导转发

    新的报头类型包括:

    • 协议ID(protocol ID):指示被封装的包的类型
    • 目的地ID(destination ID):用于路由

    开始的代码文件为badic_tunnel.p4,这里面只是基于IP转发,和上次basic_forwading实验差不多

    关于控制平面:

    • P4程序定义了一个包处理管道,但是每个表中的规则都是由控制平面插入的。当一个规则和一个数据包匹配的时候,它的操作将使用控制平面作为规则的一部分提供的参数来调用
    • 对于这个练习,我们已经提供了必要的静态控制平面条目。作为启动Mininet实例的一部分,make run 命令将在每个交换机的表中安装包处理规则。这些规则在sC-runtime.json文件中被定义,X对应交换机的编号
    • 由于控制平面视图访问myTunnel_exact 表,而该表还不存在,因此make run命令不能够与启动器代码一起工作
    • 重要提示:我们使用P4Runtime来安装控制平面规则,文件sX-runtime.json中包括table、keys、actions的名称,如并一起生成的P4Info文件中定义的(执行make run后查找build/basic.P4Info文件)。P4程序中添加或重命名表、键、操作的任何修改都反应在sC-runtime.json文件中

    二、实现

    步骤一:实现基本的隧道
    basic_tunnel.p4文件中包含了一个基于IP转发的路由实现方式。同样TODO是我们自己需要修改的部分。最终basic_tunnel.p4达到的效果是:交换机可以基于自定义封装报头做转发,同样如果是普通的IP数据包也可以做正常的IP转发

    解决方案的思路:

    1. 新的header type命名为myTunnel_t,包含两个16bit的字段:proto_id、dst_id
    2. myTunnel_t头部添加到headers结构中
    3. 更新解析器parser,可以基于etherType提取myTunnel包头和ipv4包头,etherType中myTunnel包头是0x1212。如果myTunnel后proto_id=TYPE_IPv4(0x0800),解析器parser应该能够识别提取ipv4包头
    4. 定义新的action命名为myTunnel_forward,这里知识简单的设置控制平面提供的出口编号(i.e.egress_spec field of the standard_metadata bus)
    5. 定义一个新的table命名为myTunnel_exact,匹配myTunnel包头中的dst_id字段。如果有匹配的数据包,table应当能够调用myTunnel_forward action,否则调用drop action
    6. 更新apply,如果myTunnel包头是可用的,在MyIngress控制模块应用新定义的myTunnel_exact table;如果ipv4包头是可用的,就调用ipv4_Ipm table
    7. 更新逆解析器deparser,按顺序填充ethernet、myTunnel、ipv4包头,注意只有在包头可用时逆解析器才会填充,如果解析器在提取的时候设置了隐含有效位,那么就不需要检查包头有效性
    8. 为交换机添加静态rule,以便交换机能够按照dst_id转发。参照拓扑图,配置接口以及设置IDs,这一步需要添加转发规则到sX-runtime.json文件(X代表交换机编号)
      在这里插入图片描述

    步骤二:执行

    • 运行sudo make run,编译basic_tunnel.p4,启动mininet,按照拓扑图配置switch和host
      在这里插入图片描述

    • 打开h1和h2的终端
      在这里插入图片描述

    • 每个主机都包含一个小型的基于python的消息传递客户端和服务器。在h2的xterm中,启动服务器:./recieve.py
      在这里插入图片描述

    • 首先,我们将测试没有隧道。在h1的xterm中,向h2发送一条消息:./send.py 10.0.2.2 “P4 is cool”
      在这里插入图片描述

    • 包应该在h2接收。如果检查接收到的数据包,应该看到它由以太网报头、IP报头、TCP报头和消息组成。如果你改变了目的IP地址(例如尝试发送到10.0.3.3),那么消息应该不会被h2接收,而会被h3接收。现在我们用隧道来测试。在h1的xterm中,向h2发送一条消息:./send.py 10.0.2.2 “P4 is cool” --dst_id 2
      在这里插入图片描述

    • 包应该在h2接收。如果检查接收到的数据包,应该看到它由以太网报头、隧道报头、IP报头、TCP报头和消息组成。在h1的xterm中,发送一条消息:./send.py 10.0.3.3 “P4 is cool” --dst_id 2
      在这里插入图片描述

    • 包应该在h2接收,即使该IP地址是h3的地址。这是因为当MyTunnel头在包中时,交换机不再使用IP头进行路由。键入exit或Ctrl-D以离开每个xterm和Mininet命令行。
      在这里插入图片描述

    • Python Scapy本身并不支持myTunnel头类型,所以我们提供了一个名为myTunnel_header.py的文件,它为我们新的自定义头添加了对Scapy的支持

    在真实的网络环境中通常是:数据包进入网络时会打上tunnel封装,而离开网络时再剥离tunnel封装。那么如何修改P4代码使我们的实验更接近现网的情况?

    在进入网络的第一台交换机,我们应该为myTunnel包头做一个目的IP和dst_id的映射。同时设置一个有效位,以便在逆解析器(deparser)处理时可以填充数据包。
    在离开网络的最后一台交换机,根据dst_id字段找到了出接口之后,我们还需要移除myTunnel包头。

  • 相关阅读:
    Transformer-深度学习-台湾大学李宏毅-课程笔记
    基于4G/5G协同的高密重载场景网络规划方法
    【数据结构】原来你叫“带头结点的双向循环链表”啊
    如何使用 React 和 Docusaurus 编写的一些自定义钩子(Hook)
    python常用pandas函数nlargest / nsmallest及其手动实现
    【站内题解】十六道csdn每日一练Python题解
    guzzlehttp5.3 and guzzlehttp6.7 , 同时共存。同时安装2个版本guzzlehttp
    CarbonData详细解析
    图形学学习笔记
    20220919 人脸识别
  • 原文地址:https://blog.csdn.net/weixin_46025531/article/details/124767172