为什么内核会丢弃数据包?


49

tcpdumpCtrl+ 打断C了总的摘要:

579204 packets captured
579346 packets received by filter
142 packets dropped by kernel

什么是“内核丢弃的数据包”?为什么会这样呢?


在我的情况下,我正在使用选项-s0,将其更改为-s1600(在MTU上方)为我解决了该问题。
LatinSuD

Answers:


48

从tcpdump的手册中:

``被内核丢弃的数据包''(这是由于tcpdump运行所在的OS中的操作系统中的数据包捕获机制由于缺少缓冲区空间而丢弃的数据包的数量;如果OS向应用程序报告了该信息;如果不是,它将报告为0)。

一点解释:

所述tcpdump捕获穿过网络接口原始数据包。必须根据您在命令行中指定的规则来解析和过滤数据包,这需要一些时间,因此必须对传入的数据包进行缓冲(排队)以进行处理。有时,有太多的数据包,它们被保存到缓冲区中,但是它们的保存速度比处理的要快,因此缓冲区最终会耗尽空间,因此内核会丢弃所有其他数据包,直到缓冲区中有可用空间为止。

您可以使用-B--buffer-size)选项来增加缓冲区大小,如下所示:

tcpdump -B 4096 ....

请注意,大小以千字节为单位指定,因此上面的行将缓冲区大小设置为4MB。


1
另外,我有意将kibi // mebi-更改为kg / mega-,并省略了有关libpcap的字眼,以免混淆人。
德米特里·瓦西里亚诺夫

4
另请注意,在tcpdump中对“长选项”的支持相对较新。在较旧的版本中(许多较旧的版本除外,它们不支持设置缓冲区大小)可以执行tcpdump -B 4096

另请注意,设置大型缓冲区需要花费时间。如果将缓冲区设置为疯狂值,则可能会在初始化期间错过数据包(tcpdump将其报告为“内核丢弃的数据包”)。
dgreene

26

需要考虑/尝试的另一件事是,tcpdump可能花费大量时间进行DNS查询以将IP解析为域名。如果不需要这些,请尝试添加-n(无查询)标志。例如:

tcpdump -n port 80

1
这是一个救星。并没有意识到tcpdump在转储到文件时确实降低了分辨率!使用-nn -B 4096让我得到0 packets dropped by kernel
Blanka

11

根据man tcpdump

数据包通过内核下降(这是被丢弃,由于缺乏缓冲空间,在其上tcpdump的运行操作系统的包捕获机制的包的数量,如果OS报告这些信息的应用程序;如果不是,它将报告为0)。

内核将捕获的数据包放入固定大小的捕获缓冲区中。如果tcpdump没有足够快地清空该缓冲区,内核将开始覆盖缓冲区中的旧数据包,并相应地增加丢弃的计数器。该计数器的值就是您看到的“被内核删除”。

顺便说一句,你可以调整捕获缓冲区:通过tcpdump-B与昆明植物大小选项。


2

除了手册页上所说的内容外,似乎还有其他原因可能导致内核丢弃数据包。我遇到了100%的数据包丢失tcpdump,网络上唯一的流量是每秒512B的PRBS数据包。显然,这里的缓冲区空间解释没有意义-我认为内核可以处理0.5kiB / s。

我的发行版(Ubuntu 14.04)附带的某些内容可能是在链路层上进行了一些不喜欢我的测试数据包的智能筛选。我的解决方法是创建一个新的网络名称空间,如下所示:

sudo -i
ip netns add debug
ip link set dev eth0 netns debug
ip netns exec debug bash
ifconfig eth0 1.2.3.4 up

在内部netns外壳中,以前导致问题的所有OS进程都无法tcpdump显示,并向我显示了我希望看到的所有数据包。


1

我发现使用该tcpdump -c选项很有用。这样,您可以设置数据包的数量,然后停止并无法填充缓冲区。

例如,这将捕获本地主机上的tcp请求。

tcpdump -ni lo tcp -c 20
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.