实施链接监控
说明:翻译自P4官方教程P4 Tutorial的Implementing Link Monitoring
介绍
本练习的目的是编写一个P4程序,使主机可以监视网络中所有链接的利用率。此练习基于基本的IPv4转发练习,因此请确保在尝试进行此操作之前先完成该操作。具体来说,我们将修改基本的P4程序,以处理源路由的探测数据包,从而使其能够在每个跃点处拾取出口链路利用率,并将其传递给主机以进行监视。
我们的探测包将包含以下三种报头类型:
// Top-level probe header, 指示此探测数据包到目前为止已经过了多少跳。
header probe_t {
bit<8> hop_cnt;
}
// 每个交换机在每个跃点处将数据添加到probe(探针)。
header probe_data_t {
bit<1> bos;
bit<7> swid;
bit<8> port;
bit<32> byte_cnt;
time_t last_time;
time_t cur_time;
}
// 指定交换机应该发送此probe数据包的出端口。每个跃点都有这些头之一。
header probe_fwd_t {
bit<8> egress_spec;
}
在本练习中,我们将使用Pod拓扑,该Pod拓扑由连接到四个交换机的四个主机组成,这四个交换机的连线就像在胖树拓扑的单个pod中一样。
link-monitor-topo.png为了监视链路利用率,我们的交换机将维护两个register array:
-
byte_cnt_reg
— 计算自最后一个探测数据包从端口发送以来从每个端口发送的字节数。 -
last_time_reg
— 存储最后一次从每个端口发送探测数据包的时间。
我们的P4程序将针对在P4.org的bmv2软件交换机上实现的V1Model架构编写。可以在以下位置找到V1Model的体系结构文件:/usr/local/share/p4c/p4include/v1model.p4。该文件描述了体系结构中P4可编程元素的接口,受支持的外部元素以及体系结构的标准元数据字段。我们鼓励您看看它。
剧透警报:
solution
子目录中有参考解决方案。随时将您的实现与参考进行比较。
步骤1:运行(不完整的)入门代码
该README文件所在的目录包含一个框架P4程序,link_monitor.p4
该程序实现基本的IPv4转发以及探测包的源路由。您的工作将是扩展此框架程序,以填充探测包中的字段。
在此之前,让我们编译并测试不完整的link_monitor.p4
程序:
-
在您的shell中,运行:
make run
这将:
- 编译
link_monitor.p4
和 - 在Mininet中启动pod-topo,并使用
link_monitor.p4
程序+表条目配置所有交换机,并且 - 使用pod-topo/topology.json中列出的命令配置所有主机
- 编译
-
现在,您应该看到一个Mininet命令提示符。打开以下两个
h1
终端:mininet> xterm h1 h1
-
在xterm之一中,运行
send.py
脚本以开始每秒发送一次探测数据包。这些探测数据包中的每一个均采用link-monitor-topo.png中指示的路径。./send.py
-
在另一个终端中,运行
receive.py
脚本以开始接收和解析探测数据包。这使我们可以监视网络内的链路利用率。./receive.py
报告的链路利用率和交换机端口号将始终为0,因为尚未填写探测字段。
-
在h1和h4之间运行一个iperf流:
mininet > iperf h1 h4
-
键入
exit
以保留每个xterm和Mininet命令行。然后,停止mininet:make stop
并删除所有pcap,构建文件和日志:
make clean
测量的链路利用率将与iperf报告的不一致,因为尚未填充探测数据包字段。您的目标是填写探测数据包字段,以便两个测量值一致。
关于控制平面的注释
P4程序定义了一个数据包处理管道,但是每个表中的规则都由控制平面插入。当规则与数据包匹配时,将使用控制平面提供的参数作为规则的一部分来调用其动作。
在本练习中,我们已经为您实现了控制平面逻辑。作为启动Mininet实例的一部分,该make run
命令将在每个交换机的表中安装数据包处理规则。这些定义在sX-runtime.json
文件中,其中X
对应于交换机号。
重要提示:我们使用P4Runtime安装控制平面规则。文件的内容sX-runtime.json
指的是表,键和操作的特定名称,这些名称由编译器生成的P4Info文件中定义(build/link_monitor.p4.p4info.txt
执行后查找文件make run
)。P4程序中添加或重命名表,键或操作的任何更改将需要反映在这些sX-runtime.json
文件中。
步骤2:实施链接监控逻辑
该link_monitor.p4
文件包含一个框架P4程序,其关键逻辑部分已被TODO
注释替换。您的实现应遵循此文件中给出的结构—将每个TODO
实现替换为实现缺失部分的逻辑。
以下是有关设计的更多详细信息:
Parser
- Parser已扩展,支持解析源路由探测数据包。解析器是设计中最复杂的部分,因此花一些时间来阅读它。请注意,它不包含任何TODO注释,因此您无需在此处进行任何更改。
- 为了解析探测数据包,我们使用
hdr.probe.hop_cnt
来确定数据包在到达交换机之前经过了多少跳。如果这是第一跳,则probe_data
数据包中将没有任何内容,因此我们跳过该状态并直接转换到该parse_probe_fwd
状态。在此parse_probe_fwd
状态下,我们使用该hdr.probe.hop_cnt
字段来确定egress_spec
要使用哪个标头字段执行转发,并将该端口值保存到元数据字段中,该元数据字段随后将用于执行转发。
state parse_probe {
packet.extract(hdr.probe);
meta.parser_metadata.remaining = hdr.probe.hop_cnt + 1;
transition select(hdr.probe.hop_cnt) {
0: parse_probe_fwd;
default: parse_probe_data;
}
}
state parse_probe_data {
packet.extract(hdr.probe_data.next);
transition select(hdr.probe_data.last.bos) {
1: parse_probe_fwd;
default: parse_probe_data;
}
}
state parse_probe_fwd {
packet.extract(hdr.probe_fwd.next);
meta.parser_metadata.remaining = meta.parser_metadata.remaining - 1;
// extract the forwarding data
meta.egress_spec = hdr.probe_fwd.last.egress_spec;
transition select(meta.parser_metadata.remaining) {
0: accept;
default: parse_probe_fwd;
}
}
Ingress Control
- 入口控制块看起来与
basic
练习非常相似。唯一的区别是该apply
块包含另一个条件,以使用egress_spec
解析器提取的字段转发探测数据包。它还会增加hdr.probe.hop_cnt
字段。
apply {
if (hdr.ipv4.isValid()) {
ipv4_lpm.apply();
}
else if (hdr.probe.isValid()) {
standard_metadata.egress_spec = (bit<9>)meta.egress_spec;
hdr.probe.hop_cnt = hdr.probe.hop_cnt + 1;
}
}
Egress Control
- 这是发生有趣的有状态处理的地方。它使用
byte_cnt_reg
寄存器来计算自最后一个探测数据包通过端口以来,已通过每个端口的字节数。 - 它将新的
probe_data
报头添加到数据包,并填写bos
(bottom of stack)字段和swid
(switch ID)字段。 - 待办事项:您的工作是填写其余的探测数据包字段,以确保您可以正确地测量链路利用率。
Deparser
- 只需以正确的顺序发出所有报头即可。
- 请注意,发出报头堆栈仅会发出堆栈中实际标记为有效的标头。
步骤3:运行您的解决方案
请按照步骤1中的说明进行操作。这次,测得的链路利用率应与iperf
报告内容一致。
故障排除
在开发程序时,可能会出现一些问题:
-
link_monitor.p4
可能无法编译。在这种情况下,make run
将报告编译器发出的错误并暂停。 -
link_monitor.p4
可能会编译,但无法在尝试使用P4Runtime安装的s1-runtime.json
穿透s4-runtime.json
文件中支持控制平面规则make run
。在这种情况下,make run
如果无法安装控制平面规则,将报告错误。使用这些错误消息来修复您的link_monitor.p4
实现。 -
link_monitor.p4
可能会编译,并且可能会安装控制平面规则,但是交换机可能无法以所需的方式处理数据包。这些logs/sX.log
文件包含详细的日志,描述每个交换机如何处理每个数据包。输出是详细的,可以帮助您查明实现中的逻辑错误。
清理Mininet
在上面的后两种情况下,make run
可能会使Mininet实例在后台运行。使用以下命令清除这些实例:
make stop
精神食粮
既然您已经实现了这个基本的监视框架,您是否可以考虑在网络核心中利用有关链路利用率的信息的方法?例如,您如何在主机或交换机上使用此数据来做出实时负载平衡决策?
网友评论