我在主机之间发送 TCP 数据(拓扑是使用网络命名空间和 veth 对创建的)。对于主机,我使用 NFLOG 和 tcpdump 将其入口和出口数据包保存到 pcap 文件,并在主机上执行以下命令:
# we turn off checksum offload:
sudo ethtool -K veth0 tx off sg off tso off ufo off
# we log packets with nflog:
sudo iptables -A OUTPUT -j NFLOG --nflog-group 17
sudo iptables -A INPUT -j NFLOG --nflog-group 17
# we write the packets:
sudo tcpdump -i nflog:17 -w mypcap.pcap
因此,对于所有Len为零的传出TCP 数据包,校验和总是错误的。对于出口流量拓扑中的所有主机都是如此。对于传入的流量,没有这样的问题。这是因为,正如我所检查的(通过使用 tcpdump 定期通过主机接口而不是通过 NFLOG 进行捕获),当出口流量离开主机接口时,校验和已经被纠正。
发送方 (11.0.0.5) 的 Pcap,使用 NLOG 捕获:
发送方的 Pcap (11.0.0.5),在发送方界面定期捕获:
接收器 (11.0.0.1) 处的 Pcap,使用 NLOG 捕获:
接收器 (11.0.0.1) 处的 Pcap,在接收器接口定期捕获:
因此,正如您在上图中所见,对于从 iptables NFLOG 捕获的 pcap,对于 Len 等于 0 的所有出口 TCP pcaket,TCP 校验和是错误的。可能是什么原因?
感谢您的关注!
我找到了解决问题的方法。可以使用 iptables NFQUEUE 代替 NFLOG。除了解决 TCP 校验和的问题外,这种方法的优点还在于捕获的数据包没有“Linux Netfilter NFLOG” Link-Layer 标头,即生成的 pcap 文件中的数据包只是原始 IP 数据包。
我一直在寻找解决这个问题的方法很长时间:Tc qdisc delay not seen in tcpdump recording。首先,解决方案在我看来相当不错:没有使转储文件变小的 Link-Layer 标头,TCP 校验和问题得到解决。但事实证明,对于大发送速率(当拓扑的 veth-pair 链路上没有安装网络速率/延迟时为 3Gbps)只有一半的流量被记录。也就是说,如果我在发送者捕获数据包的接口记录入口和出口流量,我会得到例如 1.7 GB 的转储,而如果我记录从内核的 iptables 捕获的流量,转储大约是 900 兆字节。NFLOG 和 NFQUEUE 解决方案都会出现发送速率受限的问题。