In this exercise, we will add support for a basic tunneling protocol to the IP router that you completed in the previous assignment. The basic switch forwards based on the destination IP address. Your jobs is to define a new header type to encapsulate the IP packet and modify the switch code, so that it instead decides the destination port using a new tunnel header
需求提取;
1.编译隧道规则
2. 采用P4Runtime下发表项
sys.path.append(
os.path.join(
os.path.dirname(
os.path.abspath(__file__)),
'../../utils/'))
sys.path 是一个字符串列表,表示解释器在导入模块时会搜索的路径集合。
__file__
是一个特殊变量,它包含了当前执行的 Python 脚本的路径。
所以这行代码的意思是将P4Runtime的utils库导入到项目中
p4info_helper =
p4runtime_lib.helper.P4InfoHelper(p4info_file_path)
在 P4Runtime 环境中,它创建了一个 P4InfoHelper 实例。这个实例用于简化和协助处理 P4Info 文件中的数据。让我们分解这个命令,以及涉及的相关概念。
定义
:P4Info 是一个由 P4 编译器生成的文件,包含了 P4 程序的元数据。这些元数据包括但不限于表、动作、计数器等的定义。作用
:P4Info 文件为 P4Runtime 控制器提供必要的信息,以便它可以正确地与 P4 编程的交换机交互。它是控制器理解 P4 编程网络设备的关键。定义
:一个 Python 库,提供了与P4Runtime操作相关函数作用
:它包装了一些复杂的 P4Runtime 操作,使得在 Python 中编写控制器代码更加简单和直观,用于简化在 P4Runtime 中操作 P4Info 数据和与 P4Runtime 交换机交互的过程。定义
:p4runtime_lib 中的一个类,用来处理 P4Info 文件。作用
:P4InfoHelper 类通过 P4Info 文件的路径初始化。它读取文件内容,并解析其中的元数据,使这些信息可以在后续操作中轻松使用。所以这行代码创建个P4InfoHelper 对象充当了 P4 程序定义和控制器之间的桥梁。通过解析 P4Info 文件,它提供了一种高效的方式来访问和操作 P4 程序中定义的各种网络实体。
当然,我会详细解释脚本中 main
函数的内容。main
函数是这个脚本的核心,主要负责设置 P4Runtime 环境并在交换机上配置隧道规则。让我们分步骤详细解释:
s1 = p4runtime_lib.bmv2.Bmv2SwitchConnection(
name='s1',
address='127.0.0.1:50051',
device_id=0,
proto_dump_file='logs/s1-p4runtime-requests.txt')
-------省略
Bmv2SwitchConnection
对象,分别代表两个虚拟交换机(s1 和 s2)。这些对象负责管理与交换机的 P4Runtime 通信。name
参数指定了交换机的名称。address
是交换机的 gRPC 地址。device_id
是交换机的设备ID。proto_dump_file
参数指定了一个文件,用于记录与交换机通信的所有 P4Runtime 消息。s1.MasterArbitrationUpdate()
s2.MasterArbitrationUpdate()
s1.SetForwardingPipelineConfig(p4info=p4info_helper.p4info,
bmv2_json_file_path=bmv2_file_path)
p4info
参数是之前解析的 P4Info 数据。bmv2_json_file_path
是 P4 编译器生成的 BMv2 JSON 文件的路径,该文件包含了 P4 程序的实现细节。writeTunnelRules(p4info_helper, ingress_sw=s1, egress_sw=s2, tunnel_id=100,
dst_eth_addr="08:00:00:00:02:22", dst_ip_addr="10.0.2.2")
writeTunnelRules(p4info_helper, ingress_sw=s2, egress_sw=s1, tunnel_id=200,
dst_eth_addr="08:00:00:00:01:11", dst_ip_addr="10.0.1.1")
writeTunnelRules
函数调用配置了隧道规则。第一个调用设置了从 s1 到 s2 的隧道,第二个则相反。p4info_helper
(用于构建 P4 表项),ingress_sw
和 egress_sw
(入口和出口交换机),tunnel_id
(隧道标识符),目标以太网地址和目标 IP 地址。# readTableRules(p4info_helper, s1)
# readTableRules(p4info_helper, s2)
while True:
sleep(2)
print('\n----- Reading tunnel counters -----')
# ... (省略了打印计数器的代码)
except KeyboardInterrupt:
print(" Shutting down.")
except grpc.RpcError as e:
printGrpcError(e)
ShutdownAllSwitchConnections()
首先我们分别把服务起来后,可以看到只有s1的1端口接收到了数据包,这是因为我们只给s1的port2和s2的port1下发了表项,而隧道规则并没有下发,所以数据包会被drop,即只会有s1连接h1的那个端口会有packet接收,其它端口没有。
p4info_helper.buildTableEntry(...)
: 这个函数用于创建一个表项。这个函数的参数包括:
table_name
: 指定要配置的表的名称。match_fields
: 定义了需要匹配的字段。action_name
: 当匹配成功时,将要执行的动作。action_params
: 与动作相关的参数。ingress_sw.WriteTableEntry(table_entry)
: 将上面创建的表项写入到交换机的入口交换。
这段代码是用于从使用P4语言编程的交换机中读取并打印配置的表项(table entries)。代码的每部分功能如下:
翻译自官网
这个 p4runtime_lib
目录包含了几个Python文件,每个文件都承担着特定的角色以支持P4网络设备的控制和管理。以下是每个文件的概要说明:
helper.py
P4InfoHelper
类,用于解析p4info文件。switch.py
SwitchConnection
类,负责获取gRPC客户端存根并建立与交换机的连接。bmv2.py
Bmv2SwitchConnection
类,它扩展了 SwitchConnection
类,并提供BMv2特有的设备负载来加载P4程序。convert.py
helper.py
使用。这些文件共同工作,为P4Runtime环境下的网络设备(如基于BMv2的交换机)提供了一个完整的控制和配置框架。通过这个库,开发人员可以更方便地与P4Runtime兼容的设备交互,包括配置网络转发规则、读取设备状态、以及管理设备连接等。