我有两个用 veth 对连接的 linux 容器。在一个容器的 veth-interface 上,我设置了 tc qdisc netem 延迟并将流量从它发送到另一个容器。如果我使用 tcpdump/wireshark 观察双方的流量,可以看出发送方和接收方的同一数据包的时间戳不会因所选延迟而有所不同。
我想更详细地了解 libpcap 将时间戳放入对应于 tc qdisc 的出口流量。我在互联网上搜索了一个方案/图像,但没有找到。我找到了这个主题(wireshark 数据包捕获点),但它建议通过多一个容器/接口来引入间接性。在我的情况下,这不是一个可能的解决方案。有没有什么方法可以解决这个问题,而不是引入额外的中间接口(即不改变拓扑),并且只通过在已经给定的 veth-interface 上记录但以可以看到延迟的方式来解决这个问题?
更新:
我太快了,所以弄错了。我的解决方案(与@AB 的答案的第一个变体相同)和@AB 的 IFB 解决方案(我已经检查过)都不能解决我的问题。a1-eth0
问题是拓扑中发送方接口的传输队列溢出:
[a1-br0 ---3Gbps---a1-eth0]---100Mbps---r1---100Mbps---r2
我太快了,只检查了a1-eth0
和 router之间链接的延迟 10ms r1
。今天我试图让延迟更高:100 毫秒、200 毫秒,结果(我得到的每个数据包延迟和速率图)对于上面的拓扑和普通拓扑开始有所不同:
[a1-eth0]---100Mbps---r1---100Mbps---r2
所以不,当然,对于准确的测试,我不能有额外的链接:Linux 桥、这个 IFB 和任何其他第三方系统都没有引入。我测试拥塞控制方案。我想在一个特定的拓扑中做到这一点。而且我不能仅仅为了绘图而改变拓扑——我的意思是,如果我的速率和延迟结果/图同时发生变化。
更新 2:
所以看起来解决方案已经找到了,如下图所示(NFLOG解决方案)。
更新 3:
这里描述了 NFLOG 解决方案的一些缺点(大的 Link-Layer 标头和错误的 TCP 校验和,用于零负载的出口 TCP 数据包),并提出了一个更好的解决方案,使用 NFQUEUE 没有任何这些问题:零长度出口数据包的 TCP 校验和错误(使用 iptables 捕获)。然而,对于我的任务(测试拥塞控制方案),NFLOG 和 NFQUEUE 都不适合。正如同一个链接所解释的,当从内核的 iptables 捕获数据包时,发送速率会受到限制(这就是我的理解)。因此,当您通过从接口捕获(即定期)在发送方进行记录时,您将获得 2 GB 转储,而如果您通过从 iptables 捕获在发送方进行记录,您将获得 1 GB 转储。大致说来。
更新 4:
最后,在我的项目中,我使用了我自己的答案中描述的 Linux 桥接解决方案。
根据Netfilter 和 General Networking示意图中的数据包流,tcpdump在egress ( qdisc ) 之后捕获 ( AF_PACKET ) 。所以在 tcpdump 中看不到延迟是正常的:延迟在初始捕获时已经存在。
您必须提前一步捕获它,因此涉及第三个系统:
S1:system1,在传出接口上运行 tcpdump
R:路由器(或网桥,在您方便时,这不会改变任何内容),运行 qdisc netem
S2:system2,在传入接口上运行 tcpdump
这意味着涉及 3 个网络堆栈,它们是真实的、vm、网络命名空间(包括ip netns、LXC、...)
或者,也可以通过使用带有镜像流量的 IFB 接口来欺骗和移动路由器(或网桥)上的每个特殊设置:允许通过一个技巧(专用于这种情况)插入 netem 排序后的入口而不是 on出口:
tc mirred 手册页中有一个基本的 IFB 用法示例:
只需在ifb0上使用 netem 而不是 sfq (在非初始网络命名空间中,
ip link add name ifbX type ifb
工作正常,没有 modprobe)。这仍然需要 3 个网络堆栈才能正常工作。
使用NFLOG
根据 JenyaKh 的建议,事实证明可以使用tcpdump在出口之前(因此在 qdisc 之前)然后在出口(在 qdisc 之后)捕获数据包:通过使用iptables(或nftables)将完整数据包记录到 netlink 日志基础设施,并且仍然使用tcpdump读取它们,然后在出口接口上再次使用tcpdump 。这仅需要 S1 上的设置(不再需要路由器/网桥)。
因此,在 S1 上使用iptables,类似于:
应该添加特定的过滤器以匹配完成的测试,因为tcpdump过滤器在 nflog 接口上受到限制(wireshark 应该更好地处理它)。
如果需要捕获答案(此处在不同的组中完成,因此需要额外的tcpdump):
根据需要,也可以将它们移至raw/OUTPUT和raw/PREROUTING。
使用tcpdump:
如果使用不同的组 (= 2) 进行输入:
然后像往常一样同时:
更新:
所以我最终使用了这个解决方案。它存在于我的解决方案中。毕竟对我来说效果很好。
我(主题启动者)已经使用 Linux 桥解决了我的问题。在这里 [ https://www.linuxquestions.org/questions/linux-networking-3/transferring-all-traffic-through-an-extra-interface-4175656515 ] 我写道,我设法使用了 Linux 桥接器,但排除了这种可能性:“但是这个解决方案不适合我的需求,因为实际上在 h1-br0 和 h1-eth0 接口之间有一个额外的以太网链路。我需要这些东西来进行性能测量,所以我不能有任何额外的以太网链路。我的意思是这个解决方案桥通过引入额外的链接弄乱了我的拓扑。”
为什么我首先忽略了解决方案?最初,我的拓扑是:
在链接上,
r1---r2
我将 netem 速率设置为 100 Mbps,在链接a1---r1
上没有速率限制。由于将路由器r1
连接到路由器的传输队列是 1000 个数据包,因此当从到r2
发送流量时,我有队列溢出的影响(一些数据包被丢弃)。这没关系。这就是它在现实世界中发生的方式,在出现瓶颈链路的情况下,路由器队列会溢出。a1
r2
现在我做所有这些研究以增加延迟和速率限制
a1---r1
。所以我想出了这个使用 Linux 桥的解决方案。但我认为这个解决方案行不通。您可以在下面看到带有 Linux 网桥的新拓扑:所以我对解决方案的问题是我预计队列溢出现在会出现在 interface 的传输队列中
a1-eth0
。也就是说,这与上图中溢出在r1
连接它的接口处的方式相同r2
。类似地。我不想要这种溢出。因为在正常拓扑中——没有使用 Linux 桥接器来测量延迟——我们没有任何传输队列溢出
a1-eth0
:a1
但是昨天我再次使用 Linux 桥(上图的第三个拓扑)创建了拓扑,并在从到的拓扑中启动了流量r2
。我检查了以 500 毫秒间隔循环a1-eth0
调用命令的传输队列的积压(队列中的当前数据包数)和使用类似命令的传输队列的积压。tc -s qdisc show dev a1-eth0
a1-br0
这就是我看到的
a1-eth0
,我收到了消息:这就是我看到的
a1-br0
,我收到了消息:因此可以看出,没有发生溢出
a1-eth0
,实际上它“看起来”不像a1-br0
发送任何东西,尽管实际上它发送了。因此 and 之间的a1-bro
链接与和 routera1-eth0
之间的链接不同(第 veth 对链接)。我不知道为什么会这样。这很奇怪,因为我检查了我可以将 netem 延迟设置设置为-- 所以它就像一个普通的界面。a1
r1
a1-br0
无论如何,我检查了桥的解决方案是否满足我的所有需求。不过,我还没有探索它为什么会起作用(我的意思是在我上面解释的意义上——队列溢出等)。
这是我在主机上运行的命令以
a1
供参考。不过,我知道,如果没有上下文,很难完全理解它们。但是,也许,它会在未来帮助某人:我应用了命令的 IP 地址拓扑也出现在此处:Pinging an interface of Linux router by another interface by this router。这是拓扑: