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包头。

猜你喜欢

转载自blog.csdn.net/weixin_46025531/article/details/124767172